fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER START
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The contents of this file are subject to the terms of the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Common Development and Distribution License (the "License").
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You may not use this file except in compliance with the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * or http://www.opensolaris.org/os/licensing.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * See the License for the specific language governing permissions
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and limitations under the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * When distributing Covered Code, include this CDDL HEADER in each
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If applicable, add the following below this CDDL HEADER, with the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner]
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER END
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
59927d313a821b7f3822314ed16fc0a44c128431Yuri Pankov
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Copyright 2000 by Cisco Systems, Inc. All rights reserved.
4246c8e92ef9ad6ada2b992b7af02832ff071bf7Jack Meng * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Use is subject to license terms.
59927d313a821b7f3822314ed16fc0a44c128431Yuri Pankov * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
59927d313a821b7f3822314ed16fc0a44c128431Yuri Pankov */
59927d313a821b7f3822314ed16fc0a44c128431Yuri Pankov
59927d313a821b7f3822314ed16fc0a44c128431Yuri Pankov/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * iSCSI Software Initiator
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/types.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/errno.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/conf.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/cmn_err.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/stat.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/pathname.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/door.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/kmem.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/socket.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/fs/snode.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <netinet/in.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/scsi/adapters/iscsi_door.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include "iscsi.h"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define ISCSI_DOOR_MAX_SEMA_VALUE 16
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic boolean_t iscsi_door_init = B_FALSE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic ksema_t iscsi_door_sema;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic krwlock_t iscsi_door_lock;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic door_handle_t iscsi_door_handle;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortetypedef struct _mybuffer {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte size_t signature;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte size_t size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte} mybuffer_t;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * iscsi_door_ini
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This function initializes the variables needed to handle the door upcall.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteboolean_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteiscsi_door_ini(void)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(!iscsi_door_init);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!iscsi_door_init) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_init(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &iscsi_door_lock,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte RW_DRIVER,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sema_init(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &iscsi_door_sema,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ISCSI_DOOR_MAX_SEMA_VALUE,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte SEMA_DRIVER,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iscsi_door_handle = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iscsi_door_init = B_TRUE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (B_TRUE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (B_FALSE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * iscsi_door_term
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This function releases the resources allocated to handle the door
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * upcall. It disconnects from the door if currently connected.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteboolean_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteiscsi_door_term(void)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(iscsi_door_init);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iscsi_door_init) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iscsi_door_init = B_FALSE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iscsi_door_unbind();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_destroy(&iscsi_door_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sema_destroy(&iscsi_door_sema);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (B_TRUE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (B_FALSE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * iscsi_door_bind
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This function tries to connect the iscsi_door. If it succeeds
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * it keeps the vnode.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteboolean_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteiscsi_door_bind(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int did
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte door_handle_t new_handle;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte new_handle = door_ki_lookup(did);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (new_handle == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* The lookup failed. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (B_FALSE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* The new handle is stored. If we had one, it is released. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&iscsi_door_lock, RW_WRITER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iscsi_door_handle != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte door_ki_rele(iscsi_door_handle);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iscsi_door_handle = new_handle;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&iscsi_door_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (B_TRUE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * iscsi_door_unbind
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This function releases the current door handle.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteiscsi_door_unbind(void)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&iscsi_door_lock, RW_WRITER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iscsi_door_handle != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte door_ki_rele(iscsi_door_handle);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iscsi_door_handle = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&iscsi_door_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * iscsi_door_upcall
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This function tries to call the iscsi_door.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteboolean_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteiscsi_door_upcall(door_arg_t *arg)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int error;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This semaphore limits the number of simultaneous calls
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to the door.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sema_p(&iscsi_door_sema);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The mutex protecting the iscsi_door_handle is entered.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_enter(&iscsi_door_lock, RW_READER);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iscsi_door_handle == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* There's no door handle. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&iscsi_door_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sema_v(&iscsi_door_sema);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (B_FALSE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte error = door_ki_upcall(iscsi_door_handle, arg);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_exit(&iscsi_door_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sema_v(&iscsi_door_sema);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (error != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (B_FALSE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (B_TRUE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * kfreehostent
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This function frees the memory returned by kgetipnodebyname.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortekfreehostent(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct hostent *hptr
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mybuffer_t *buffer;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(hptr != NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (hptr) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte buffer = (mybuffer_t *)((char *)hptr - sizeof (mybuffer_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(buffer->signature == ISCSI_DOOR_REQ_SIGNATURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (buffer->signature == ISCSI_DOOR_REQ_SIGNATURE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free((void *)buffer, buffer->size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* A message should be logged here. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * kgetipnodebyname
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This function builds a request that will be sent to the iscsi_door.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The iSCSI door after receiving the request calls getipnodebyaddr().
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * for more information on the input, output parameter and return value,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * consult the man page for getipnodebyname().
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Before calling the iscsi door this function tries to do the conversion
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * locally. If a name resolution is needed the iscsi door is called.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * There's some limitations to the information returned by this function.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Only one address of the address list returned by getipnodebyname() is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * returned. The other parameters of the structure should be ignored.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestruct hostent *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortekgetipnodebyname(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte const char *name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int af,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int flags,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int *error_num
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte door_arg_t arg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mybuffer_t *buffer;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte size_t msg_size = ISCSI_DOOR_MAX_DATA_SIZE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte size_t hostent_size = ISCSI_DOOR_MAX_DATA_SIZE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte size_t buffer_size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte getipnodebyname_req_t *req;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte getipnodebyname_cnf_t *cnf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct hostent *hptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte buffer_size = msg_size + hostent_size + sizeof (mybuffer_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte buffer = (mybuffer_t *)kmem_zalloc(buffer_size, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (buffer) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The buffer was successfully allocated.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Buffer
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * +--------------------+ <--- buffer
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * | mybuffer_t |
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * +--------------------+ <--- hptr
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * | |
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * | |
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * | hostent_size |
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * | |
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * | |
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * | |
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * +--------------------+ <--- req, cnf
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * | |
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * | |
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * | |
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * | msg_size |
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * | |
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * | |
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * | |
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * +--------------------+
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte buffer->signature = ISCSI_DOOR_REQ_SIGNATURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte buffer->size = buffer_size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hptr = (struct hostent *)((char *)buffer + sizeof (mybuffer_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte req = (getipnodebyname_req_t *)((char *)hptr + hostent_size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cnf = (getipnodebyname_cnf_t *)((char *)hptr + hostent_size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hostent_size -= sizeof (struct hostent);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We try first locally. If the conversion cannot be done
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * by inet_pton the door is called.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The cnf address is used as output buffer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * inet_pton returns '1' if the conversion was successful.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (af) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case AF_INET:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hptr->h_length = sizeof (struct in_addr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case AF_INET6:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hptr->h_length = sizeof (struct in6_addr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kfreehostent(hptr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *error_num = NO_RECOVERY;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((msg_size < hptr->h_length) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (hostent_size < sizeof (char *))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kfreehostent(hptr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *error_num = NO_RECOVERY;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (inet_pton(af, (char *)name, cnf) == 1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * inet_pton converted the string successfully.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hptr->h_addrtype = af;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hptr->h_addr_list = (char **)((char *)hptr +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (struct hostent));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *hptr->h_addr_list = (char *)cnf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (hptr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The name couldn't ne converted by inet_pton. The door is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * called.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Header initialization. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte req->hdr.signature = ISCSI_DOOR_REQ_SIGNATURE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte req->hdr.version = ISCSI_DOOR_REQ_VERSION_1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte req->hdr.opcode = ISCSI_DOOR_GETIPNODEBYNAME_REQ;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Body initialization. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte req->name_length = strlen(name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (req->name_length >
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (msg_size - sizeof (getipnodebyname_req_t) - 1)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kfreehostent(hptr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *error_num = NO_RECOVERY;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte req->name_offset = sizeof (getipnodebyname_req_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte req->af = af;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte req->flags = flags;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((char *)req + req->name_offset),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte req->name_length);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Door argument initialization. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte arg.data_ptr = (char *)req;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte arg.data_size = msg_size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte arg.desc_num = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte arg.desc_ptr = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte arg.rbuf = (char *)cnf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte arg.rsize = msg_size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iscsi_door_upcall(&arg) == B_FALSE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* The door call failed */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kfreehostent(hptr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *error_num = NO_RECOVERY;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The door call itself was successful. The value returned
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * in arg.rbuf should be cnf, but we never know.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cnf = (getipnodebyname_cnf_t *)arg.rbuf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((cnf == NULL) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (arg.rsize < sizeof (getipnodebyname_cnf_t)) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (cnf->hdr.signature != ISCSI_DOOR_REQ_SIGNATURE) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (cnf->hdr.version != ISCSI_DOOR_REQ_VERSION_1) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (cnf->hdr.opcode != ISCSI_DOOR_GETIPNODEBYNAME_CNF) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((cnf->hdr.status != ISCSI_DOOR_STATUS_SUCCESS) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (cnf->hdr.status != ISCSI_DOOR_STATUS_MORE))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* The door didn't like the request */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kfreehostent(hptr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *error_num = NO_RECOVERY;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cnf->h_addr_list_length == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kfreehostent(hptr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *error_num = HOST_NOT_FOUND;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hptr->h_addrtype = cnf->h_addrtype;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hptr->h_length = cnf->h_addrlen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hptr->h_addr_list = (char **)((char *)hptr +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (struct hostent));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *hptr->h_addr_list = ((char *)cnf + cnf->h_addr_list_offset);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (hptr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *error_num = NO_RECOVERY;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}