xref: /titanic_51/usr/src/cmd/isns/isnsd/func.c (revision fcf3ce441efd61da9bb2884968af01cb7c1452cc)
1*fcf3ce44SJohn Forte /*
2*fcf3ce44SJohn Forte  * CDDL HEADER START
3*fcf3ce44SJohn Forte  *
4*fcf3ce44SJohn Forte  * The contents of this file are subject to the terms of the
5*fcf3ce44SJohn Forte  * Common Development and Distribution License (the "License").
6*fcf3ce44SJohn Forte  * You may not use this file except in compliance with the License.
7*fcf3ce44SJohn Forte  *
8*fcf3ce44SJohn Forte  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*fcf3ce44SJohn Forte  * or http://www.opensolaris.org/os/licensing.
10*fcf3ce44SJohn Forte  * See the License for the specific language governing permissions
11*fcf3ce44SJohn Forte  * and limitations under the License.
12*fcf3ce44SJohn Forte  *
13*fcf3ce44SJohn Forte  * When distributing Covered Code, include this CDDL HEADER in each
14*fcf3ce44SJohn Forte  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*fcf3ce44SJohn Forte  * If applicable, add the following below this CDDL HEADER, with the
16*fcf3ce44SJohn Forte  * fields enclosed by brackets "[]" replaced with your own identifying
17*fcf3ce44SJohn Forte  * information: Portions Copyright [yyyy] [name of copyright owner]
18*fcf3ce44SJohn Forte  *
19*fcf3ce44SJohn Forte  * CDDL HEADER END
20*fcf3ce44SJohn Forte  */
21*fcf3ce44SJohn Forte 
22*fcf3ce44SJohn Forte /*
23*fcf3ce44SJohn Forte  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24*fcf3ce44SJohn Forte  * Use is subject to license terms.
25*fcf3ce44SJohn Forte  */
26*fcf3ce44SJohn Forte 
27*fcf3ce44SJohn Forte #include <stdio.h>
28*fcf3ce44SJohn Forte #include <stdlib.h>
29*fcf3ce44SJohn Forte #include <sys/types.h>
30*fcf3ce44SJohn Forte #include <sys/socket.h>
31*fcf3ce44SJohn Forte #include <netinet/in.h>
32*fcf3ce44SJohn Forte #include <arpa/inet.h>
33*fcf3ce44SJohn Forte 
34*fcf3ce44SJohn Forte #include "isns_server.h"
35*fcf3ce44SJohn Forte #include "isns_msgq.h"
36*fcf3ce44SJohn Forte #include "isns_func.h"
37*fcf3ce44SJohn Forte #include "isns_cache.h"
38*fcf3ce44SJohn Forte #include "isns_obj.h"
39*fcf3ce44SJohn Forte #include "isns_dd.h"
40*fcf3ce44SJohn Forte #include "isns_pdu.h"
41*fcf3ce44SJohn Forte #include "isns_qry.h"
42*fcf3ce44SJohn Forte #include "isns_scn.h"
43*fcf3ce44SJohn Forte #include "isns_utils.h"
44*fcf3ce44SJohn Forte #include "isns_cfg.h"
45*fcf3ce44SJohn Forte #include "isns_esi.h"
46*fcf3ce44SJohn Forte #include "isns_provider.h"
47*fcf3ce44SJohn Forte #include "isns_log.h"
48*fcf3ce44SJohn Forte 
49*fcf3ce44SJohn Forte /*
50*fcf3ce44SJohn Forte  * extern global variables
51*fcf3ce44SJohn Forte  */
52*fcf3ce44SJohn Forte #ifdef DEBUG
53*fcf3ce44SJohn Forte extern int verbose_mc;
54*fcf3ce44SJohn Forte extern int verbose_tc;
55*fcf3ce44SJohn Forte #endif
56*fcf3ce44SJohn Forte extern const int NUM_OF_ATTRS[MAX_OBJ_TYPE_FOR_SIZE];
57*fcf3ce44SJohn Forte extern const int NUM_OF_CHILD[MAX_OBJ_TYPE];
58*fcf3ce44SJohn Forte extern const int TYPE_OF_PARENT[MAX_OBJ_TYPE_FOR_SIZE];
59*fcf3ce44SJohn Forte extern const int UID_ATTR_INDEX[MAX_OBJ_TYPE_FOR_SIZE];
60*fcf3ce44SJohn Forte extern const int TAG_RANGE[MAX_OBJ_TYPE][3];
61*fcf3ce44SJohn Forte 
62*fcf3ce44SJohn Forte /* scn message queue */
63*fcf3ce44SJohn Forte extern msg_queue_t *scn_q;
64*fcf3ce44SJohn Forte 
65*fcf3ce44SJohn Forte /*
66*fcf3ce44SJohn Forte  * extern functions.
67*fcf3ce44SJohn Forte  */
68*fcf3ce44SJohn Forte 
69*fcf3ce44SJohn Forte /*
70*fcf3ce44SJohn Forte  * local variables
71*fcf3ce44SJohn Forte  */
72*fcf3ce44SJohn Forte 
73*fcf3ce44SJohn Forte /*
74*fcf3ce44SJohn Forte  * local functions.
75*fcf3ce44SJohn Forte  */
76*fcf3ce44SJohn Forte static int dev_attr_reg(conn_arg_t *);
77*fcf3ce44SJohn Forte static int dev_attr_qry(conn_arg_t *);
78*fcf3ce44SJohn Forte static int dev_get_next(conn_arg_t *);
79*fcf3ce44SJohn Forte static int dev_dereg(conn_arg_t *);
80*fcf3ce44SJohn Forte static int scn_reg(conn_arg_t *);
81*fcf3ce44SJohn Forte static int scn_dereg(conn_arg_t *);
82*fcf3ce44SJohn Forte static int dd_reg(conn_arg_t *);
83*fcf3ce44SJohn Forte static int dd_dereg(conn_arg_t *);
84*fcf3ce44SJohn Forte static int dds_reg(conn_arg_t *);
85*fcf3ce44SJohn Forte static int dds_dereg(conn_arg_t *);
86*fcf3ce44SJohn Forte static int msg_error(conn_arg_t *);
87*fcf3ce44SJohn Forte 
88*fcf3ce44SJohn Forte /*
89*fcf3ce44SJohn Forte  * ****************************************************************************
90*fcf3ce44SJohn Forte  *
91*fcf3ce44SJohn Forte  * packet_get_source:
92*fcf3ce44SJohn Forte  *	get the source attributes of the packet.
93*fcf3ce44SJohn Forte  *
94*fcf3ce44SJohn Forte  * conn	- the argument of the connection.
95*fcf3ce44SJohn Forte  * return - error code.
96*fcf3ce44SJohn Forte  *
97*fcf3ce44SJohn Forte  * ****************************************************************************
98*fcf3ce44SJohn Forte  */
99*fcf3ce44SJohn Forte static int
100*fcf3ce44SJohn Forte packet_get_source(
101*fcf3ce44SJohn Forte 	conn_arg_t *conn
102*fcf3ce44SJohn Forte )
103*fcf3ce44SJohn Forte {
104*fcf3ce44SJohn Forte 	int ec = 0;
105*fcf3ce44SJohn Forte 
106*fcf3ce44SJohn Forte 	isns_pdu_t *pdu = conn->in_packet.pdu;
107*fcf3ce44SJohn Forte 	isns_tlv_t *source = pdu_get_source(pdu);
108*fcf3ce44SJohn Forte 
109*fcf3ce44SJohn Forte 	if (source == NULL) {
110*fcf3ce44SJohn Forte 		ec = ISNS_RSP_SRC_ABSENT;
111*fcf3ce44SJohn Forte 	} else if (source->attr_id != ISNS_ISCSI_NAME_ATTR_ID ||
112*fcf3ce44SJohn Forte 	    source->attr_len == 0) {
113*fcf3ce44SJohn Forte 		ec = ISNS_RSP_SRC_UNKNOWN;
114*fcf3ce44SJohn Forte 	}
115*fcf3ce44SJohn Forte 
116*fcf3ce44SJohn Forte 	if (ec == 0) {
117*fcf3ce44SJohn Forte 		conn->in_packet.source = source;
118*fcf3ce44SJohn Forte 	}
119*fcf3ce44SJohn Forte 
120*fcf3ce44SJohn Forte 	return (ec);
121*fcf3ce44SJohn Forte }
122*fcf3ce44SJohn Forte 
123*fcf3ce44SJohn Forte /*
124*fcf3ce44SJohn Forte  * ****************************************************************************
125*fcf3ce44SJohn Forte  *
126*fcf3ce44SJohn Forte  * packet_get_key:
127*fcf3ce44SJohn Forte  *	get the key attributes of the packet.
128*fcf3ce44SJohn Forte  *
129*fcf3ce44SJohn Forte  * conn	- the argument of the connection.
130*fcf3ce44SJohn Forte  * return - error code.
131*fcf3ce44SJohn Forte  *
132*fcf3ce44SJohn Forte  * ****************************************************************************
133*fcf3ce44SJohn Forte  */
134*fcf3ce44SJohn Forte static int
135*fcf3ce44SJohn Forte packet_get_key(
136*fcf3ce44SJohn Forte 	conn_arg_t *conn
137*fcf3ce44SJohn Forte )
138*fcf3ce44SJohn Forte {
139*fcf3ce44SJohn Forte 	int ec = 0;
140*fcf3ce44SJohn Forte 
141*fcf3ce44SJohn Forte 	isns_pdu_t *pdu = conn->in_packet.pdu;
142*fcf3ce44SJohn Forte 	isns_tlv_t *key;
143*fcf3ce44SJohn Forte 	size_t key_len;
144*fcf3ce44SJohn Forte 
145*fcf3ce44SJohn Forte 	key = pdu_get_key(pdu, &key_len);
146*fcf3ce44SJohn Forte 
147*fcf3ce44SJohn Forte 	conn->in_packet.key = key;
148*fcf3ce44SJohn Forte 	conn->in_packet.key_len = key_len;
149*fcf3ce44SJohn Forte 
150*fcf3ce44SJohn Forte 	return (ec);
151*fcf3ce44SJohn Forte }
152*fcf3ce44SJohn Forte 
153*fcf3ce44SJohn Forte /*
154*fcf3ce44SJohn Forte  * ****************************************************************************
155*fcf3ce44SJohn Forte  *
156*fcf3ce44SJohn Forte  * packet_get_operand:
157*fcf3ce44SJohn Forte  *	get the operating attributes of the packet.
158*fcf3ce44SJohn Forte  *
159*fcf3ce44SJohn Forte  * conn	- the argument of the connection.
160*fcf3ce44SJohn Forte  * return - error code.
161*fcf3ce44SJohn Forte  *
162*fcf3ce44SJohn Forte  * ****************************************************************************
163*fcf3ce44SJohn Forte  */
164*fcf3ce44SJohn Forte static int
165*fcf3ce44SJohn Forte packet_get_operand(
166*fcf3ce44SJohn Forte 	conn_arg_t *conn
167*fcf3ce44SJohn Forte )
168*fcf3ce44SJohn Forte {
169*fcf3ce44SJohn Forte 	int ec = 0;
170*fcf3ce44SJohn Forte 
171*fcf3ce44SJohn Forte 	isns_pdu_t *pdu = conn->in_packet.pdu;
172*fcf3ce44SJohn Forte 	isns_tlv_t *op;
173*fcf3ce44SJohn Forte 	size_t op_len;
174*fcf3ce44SJohn Forte 
175*fcf3ce44SJohn Forte 	op = pdu_get_operand(pdu, &op_len);
176*fcf3ce44SJohn Forte 
177*fcf3ce44SJohn Forte 	conn->in_packet.op = op;
178*fcf3ce44SJohn Forte 	conn->in_packet.op_len = op_len;
179*fcf3ce44SJohn Forte 
180*fcf3ce44SJohn Forte 	return (ec);
181*fcf3ce44SJohn Forte }
182*fcf3ce44SJohn Forte 
183*fcf3ce44SJohn Forte /*
184*fcf3ce44SJohn Forte  * ****************************************************************************
185*fcf3ce44SJohn Forte  *
186*fcf3ce44SJohn Forte  * packet_split_verify:
187*fcf3ce44SJohn Forte  *	split and verify the packet, get the apporiate locking type and
188*fcf3ce44SJohn Forte  *	function handler for the packet.
189*fcf3ce44SJohn Forte  *
190*fcf3ce44SJohn Forte  * conn	- the argument of the connection.
191*fcf3ce44SJohn Forte  * return - error code.
192*fcf3ce44SJohn Forte  *
193*fcf3ce44SJohn Forte  * ****************************************************************************
194*fcf3ce44SJohn Forte  */
195*fcf3ce44SJohn Forte int
196*fcf3ce44SJohn Forte packet_split_verify(
197*fcf3ce44SJohn Forte 	conn_arg_t *conn
198*fcf3ce44SJohn Forte )
199*fcf3ce44SJohn Forte {
200*fcf3ce44SJohn Forte 	int ec = 0;
201*fcf3ce44SJohn Forte 
202*fcf3ce44SJohn Forte 	isns_pdu_t *pdu = conn->in_packet.pdu;
203*fcf3ce44SJohn Forte 
204*fcf3ce44SJohn Forte 	int (*handler)(conn_arg_t *) = msg_error;
205*fcf3ce44SJohn Forte 	int lock = CACHE_NO_ACTION;
206*fcf3ce44SJohn Forte 
207*fcf3ce44SJohn Forte 	if (pdu->version != ISNSP_VERSION) {
208*fcf3ce44SJohn Forte 		ec = ISNS_RSP_VER_NOT_SUPPORTED;
209*fcf3ce44SJohn Forte 	} else {
210*fcf3ce44SJohn Forte 		switch (pdu->func_id) {
211*fcf3ce44SJohn Forte 		case ISNS_DEV_ATTR_REG:
212*fcf3ce44SJohn Forte 			lock = CACHE_WRITE;
213*fcf3ce44SJohn Forte 			handler = dev_attr_reg;
214*fcf3ce44SJohn Forte 			break;
215*fcf3ce44SJohn Forte 		case ISNS_DEV_ATTR_QRY:
216*fcf3ce44SJohn Forte 			lock = CACHE_READ;
217*fcf3ce44SJohn Forte 			handler = dev_attr_qry;
218*fcf3ce44SJohn Forte 			break;
219*fcf3ce44SJohn Forte 		case ISNS_DEV_GET_NEXT:
220*fcf3ce44SJohn Forte 			lock = CACHE_READ;
221*fcf3ce44SJohn Forte 			handler = dev_get_next;
222*fcf3ce44SJohn Forte 			break;
223*fcf3ce44SJohn Forte 		case ISNS_DEV_DEREG:
224*fcf3ce44SJohn Forte 			lock = CACHE_WRITE;
225*fcf3ce44SJohn Forte 			handler = dev_dereg;
226*fcf3ce44SJohn Forte 			break;
227*fcf3ce44SJohn Forte 		case ISNS_SCN_REG:
228*fcf3ce44SJohn Forte 			if (scn_q != NULL) {
229*fcf3ce44SJohn Forte 				lock = CACHE_WRITE;
230*fcf3ce44SJohn Forte 				handler = scn_reg;
231*fcf3ce44SJohn Forte 			} else {
232*fcf3ce44SJohn Forte 				ec = ISNS_RSP_SCN_REGIS_REJECTED;
233*fcf3ce44SJohn Forte 			}
234*fcf3ce44SJohn Forte 			break;
235*fcf3ce44SJohn Forte 		case ISNS_SCN_DEREG:
236*fcf3ce44SJohn Forte 			if (scn_q != NULL) {
237*fcf3ce44SJohn Forte 				lock = CACHE_WRITE;
238*fcf3ce44SJohn Forte 				handler = scn_dereg;
239*fcf3ce44SJohn Forte 			} else {
240*fcf3ce44SJohn Forte 				ec = ISNS_RSP_SCN_REGIS_REJECTED;
241*fcf3ce44SJohn Forte 			}
242*fcf3ce44SJohn Forte 			break;
243*fcf3ce44SJohn Forte 		case ISNS_SCN_EVENT:
244*fcf3ce44SJohn Forte 			ec = ISNS_RSP_MSG_NOT_SUPPORTED;
245*fcf3ce44SJohn Forte 			break;
246*fcf3ce44SJohn Forte 		case ISNS_DD_REG:
247*fcf3ce44SJohn Forte 			lock = CACHE_WRITE;
248*fcf3ce44SJohn Forte 			handler = dd_reg;
249*fcf3ce44SJohn Forte 			break;
250*fcf3ce44SJohn Forte 		case ISNS_DD_DEREG:
251*fcf3ce44SJohn Forte 			lock = CACHE_WRITE;
252*fcf3ce44SJohn Forte 			handler = dd_dereg;
253*fcf3ce44SJohn Forte 			break;
254*fcf3ce44SJohn Forte 		case ISNS_DDS_REG:
255*fcf3ce44SJohn Forte 			lock = CACHE_WRITE;
256*fcf3ce44SJohn Forte 			handler = dds_reg;
257*fcf3ce44SJohn Forte 			break;
258*fcf3ce44SJohn Forte 		case ISNS_DDS_DEREG:
259*fcf3ce44SJohn Forte 			lock = CACHE_WRITE;
260*fcf3ce44SJohn Forte 			handler = dds_dereg;
261*fcf3ce44SJohn Forte 			break;
262*fcf3ce44SJohn Forte 		default:
263*fcf3ce44SJohn Forte 			ec = ISNS_RSP_MSG_NOT_SUPPORTED;
264*fcf3ce44SJohn Forte 			break;
265*fcf3ce44SJohn Forte 		}
266*fcf3ce44SJohn Forte 	}
267*fcf3ce44SJohn Forte 
268*fcf3ce44SJohn Forte 	if (ISNS_OPERATION_TYPE_ENABLED()) {
269*fcf3ce44SJohn Forte 		char buf[INET6_ADDRSTRLEN];
270*fcf3ce44SJohn Forte 		struct sockaddr_storage *ssp = &conn->ss;
271*fcf3ce44SJohn Forte 		struct sockaddr_in *sinp = (struct sockaddr_in *)ssp;
272*fcf3ce44SJohn Forte 		if (ssp->ss_family == AF_INET) {
273*fcf3ce44SJohn Forte 			(void) inet_ntop(AF_INET, (void *)&(sinp->sin_addr),
274*fcf3ce44SJohn Forte 			    buf, sizeof (buf));
275*fcf3ce44SJohn Forte 		} else {
276*fcf3ce44SJohn Forte 			(void) inet_ntop(AF_INET6, (void *)&(sinp->sin_addr),
277*fcf3ce44SJohn Forte 			    buf, sizeof (buf));
278*fcf3ce44SJohn Forte 		}
279*fcf3ce44SJohn Forte 		ISNS_OPERATION_TYPE((uintptr_t)buf, pdu->func_id);
280*fcf3ce44SJohn Forte 	}
281*fcf3ce44SJohn Forte 
282*fcf3ce44SJohn Forte 	conn->lock = lock;
283*fcf3ce44SJohn Forte 	conn->handler = handler;
284*fcf3ce44SJohn Forte 
285*fcf3ce44SJohn Forte 	/* packet split & verify */
286*fcf3ce44SJohn Forte 	if (ec == 0) {
287*fcf3ce44SJohn Forte 		ec = packet_get_source(conn);
288*fcf3ce44SJohn Forte 		if (ec == 0) {
289*fcf3ce44SJohn Forte 			ec = packet_get_key(conn);
290*fcf3ce44SJohn Forte 			if (ec == 0) {
291*fcf3ce44SJohn Forte 				ec = packet_get_operand(conn);
292*fcf3ce44SJohn Forte 			}
293*fcf3ce44SJohn Forte 		}
294*fcf3ce44SJohn Forte 	}
295*fcf3ce44SJohn Forte 
296*fcf3ce44SJohn Forte 	conn->ec = ec;
297*fcf3ce44SJohn Forte 
298*fcf3ce44SJohn Forte 	return (ec);
299*fcf3ce44SJohn Forte }
300*fcf3ce44SJohn Forte 
301*fcf3ce44SJohn Forte /*
302*fcf3ce44SJohn Forte  * ****************************************************************************
303*fcf3ce44SJohn Forte  *
304*fcf3ce44SJohn Forte  * setup_key_lcp:
305*fcf3ce44SJohn Forte  *	setup the lookup control data for looking up the object
306*fcf3ce44SJohn Forte  *	which the key attributes identify.
307*fcf3ce44SJohn Forte  *
308*fcf3ce44SJohn Forte  * lcp	- the pointer of the lookup control data.
309*fcf3ce44SJohn Forte  * key	- the key attributes.
310*fcf3ce44SJohn Forte  * key_len	- the length of the key attributes.
311*fcf3ce44SJohn Forte  * return	- the pointer of the lookup control data or
312*fcf3ce44SJohn Forte  *		  NULL if there is an error.
313*fcf3ce44SJohn Forte  *
314*fcf3ce44SJohn Forte  * ****************************************************************************
315*fcf3ce44SJohn Forte  */
316*fcf3ce44SJohn Forte static int
317*fcf3ce44SJohn Forte setup_key_lcp(
318*fcf3ce44SJohn Forte 	lookup_ctrl_t *lcp,
319*fcf3ce44SJohn Forte 	isns_tlv_t *key,
320*fcf3ce44SJohn Forte 	uint16_t key_len
321*fcf3ce44SJohn Forte )
322*fcf3ce44SJohn Forte {
323*fcf3ce44SJohn Forte 	int ec = 0;
324*fcf3ce44SJohn Forte 
325*fcf3ce44SJohn Forte 	uint8_t *value = &key->attr_value[0];
326*fcf3ce44SJohn Forte 
327*fcf3ce44SJohn Forte 	lcp->curr_uid = 0;
328*fcf3ce44SJohn Forte 	lcp->op[0] = 0;
329*fcf3ce44SJohn Forte 
330*fcf3ce44SJohn Forte 	switch (key->attr_id) {
331*fcf3ce44SJohn Forte 	case ISNS_EID_ATTR_ID:
332*fcf3ce44SJohn Forte 		if (key->attr_len >= 4) {
333*fcf3ce44SJohn Forte 			lcp->type = OBJ_ENTITY;
334*fcf3ce44SJohn Forte 			lcp->id[0] = ATTR_INDEX_ENTITY(ISNS_EID_ATTR_ID);
335*fcf3ce44SJohn Forte 			lcp->op[0] = OP_STRING;
336*fcf3ce44SJohn Forte 			lcp->data[0].ptr = (uchar_t *)value;
337*fcf3ce44SJohn Forte 			lcp->op[1] = 0;
338*fcf3ce44SJohn Forte 		}
339*fcf3ce44SJohn Forte 		break;
340*fcf3ce44SJohn Forte 	case ISNS_ISCSI_NAME_ATTR_ID:
341*fcf3ce44SJohn Forte 		if (key->attr_len >= 4) {
342*fcf3ce44SJohn Forte 			lcp->type = OBJ_ISCSI;
343*fcf3ce44SJohn Forte 			lcp->id[0] = ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID);
344*fcf3ce44SJohn Forte 			lcp->op[0] = OP_STRING;
345*fcf3ce44SJohn Forte 			lcp->data[0].ptr = (uchar_t *)value;
346*fcf3ce44SJohn Forte 			lcp->op[1] = 0;
347*fcf3ce44SJohn Forte 		} else {
348*fcf3ce44SJohn Forte 			ec = ISNS_RSP_MSG_FORMAT_ERROR;
349*fcf3ce44SJohn Forte 		}
350*fcf3ce44SJohn Forte 		break;
351*fcf3ce44SJohn Forte 	case ISNS_PORTAL_IP_ADDR_ATTR_ID:
352*fcf3ce44SJohn Forte 		if (key->attr_len == sizeof (in6_addr_t)) {
353*fcf3ce44SJohn Forte 			lcp->id[0] = ATTR_INDEX_PORTAL(
354*fcf3ce44SJohn Forte 			    ISNS_PORTAL_IP_ADDR_ATTR_ID);
355*fcf3ce44SJohn Forte 			lcp->op[0] = OP_MEMORY_IP6;
356*fcf3ce44SJohn Forte 			lcp->data[0].ip = (in6_addr_t *)value;
357*fcf3ce44SJohn Forte 			NEXT_TLV(key, key_len);
358*fcf3ce44SJohn Forte 			if (key_len <= 8 ||
359*fcf3ce44SJohn Forte 			    key->attr_len != 4 ||
360*fcf3ce44SJohn Forte 			    key->attr_id != ISNS_PORTAL_PORT_ATTR_ID) {
361*fcf3ce44SJohn Forte 				return (ISNS_RSP_MSG_FORMAT_ERROR);
362*fcf3ce44SJohn Forte 			}
363*fcf3ce44SJohn Forte 			lcp->type = OBJ_PORTAL;
364*fcf3ce44SJohn Forte 			value = &key->attr_value[0];
365*fcf3ce44SJohn Forte 			lcp->id[1] = ATTR_INDEX_PORTAL(
366*fcf3ce44SJohn Forte 			    ISNS_PORTAL_PORT_ATTR_ID);
367*fcf3ce44SJohn Forte 			lcp->op[1] = OP_INTEGER;
368*fcf3ce44SJohn Forte 			lcp->data[1].ui = ntohl(*(uint32_t *)value);
369*fcf3ce44SJohn Forte 			lcp->op[2] = 0;
370*fcf3ce44SJohn Forte 		} else {
371*fcf3ce44SJohn Forte 			ec = ISNS_RSP_MSG_FORMAT_ERROR;
372*fcf3ce44SJohn Forte 		}
373*fcf3ce44SJohn Forte 		break;
374*fcf3ce44SJohn Forte 	case ISNS_PG_ISCSI_NAME_ATTR_ID:
375*fcf3ce44SJohn Forte 		if (key->attr_len < 4) {
376*fcf3ce44SJohn Forte 			return (ISNS_RSP_MSG_FORMAT_ERROR);
377*fcf3ce44SJohn Forte 		}
378*fcf3ce44SJohn Forte 		lcp->id[0] = ATTR_INDEX_PG(ISNS_PG_ISCSI_NAME_ATTR_ID);
379*fcf3ce44SJohn Forte 		lcp->op[0] = OP_STRING;
380*fcf3ce44SJohn Forte 		lcp->data[0].ptr = (uchar_t *)value;
381*fcf3ce44SJohn Forte 		NEXT_TLV(key, key_len);
382*fcf3ce44SJohn Forte 		if (key_len <= 8 ||
383*fcf3ce44SJohn Forte 		    key->attr_len != sizeof (in6_addr_t) ||
384*fcf3ce44SJohn Forte 		    key->attr_id != ISNS_PG_PORTAL_IP_ADDR_ATTR_ID) {
385*fcf3ce44SJohn Forte 			return (ISNS_RSP_MSG_FORMAT_ERROR);
386*fcf3ce44SJohn Forte 		}
387*fcf3ce44SJohn Forte 		value = &key->attr_value[0];
388*fcf3ce44SJohn Forte 		lcp->id[1] = ATTR_INDEX_PG(ISNS_PG_PORTAL_IP_ADDR_ATTR_ID);
389*fcf3ce44SJohn Forte 		lcp->op[1] = OP_MEMORY_IP6;
390*fcf3ce44SJohn Forte 		lcp->data[1].ip = (in6_addr_t *)value;
391*fcf3ce44SJohn Forte 		NEXT_TLV(key, key_len);
392*fcf3ce44SJohn Forte 		if (key_len <= 8 ||
393*fcf3ce44SJohn Forte 		    key->attr_len != 4 ||
394*fcf3ce44SJohn Forte 		    key->attr_id != ISNS_PG_PORTAL_PORT_ATTR_ID) {
395*fcf3ce44SJohn Forte 			return (ISNS_RSP_MSG_FORMAT_ERROR);
396*fcf3ce44SJohn Forte 		}
397*fcf3ce44SJohn Forte 		value = &key->attr_value[0];
398*fcf3ce44SJohn Forte 		lcp->id[2] = ATTR_INDEX_PG(ISNS_PG_PORTAL_PORT_ATTR_ID);
399*fcf3ce44SJohn Forte 		lcp->op[2] = OP_INTEGER;
400*fcf3ce44SJohn Forte 		lcp->data[2].ui = ntohl(*(uint32_t *)value);
401*fcf3ce44SJohn Forte 		lcp->type = OBJ_PG;
402*fcf3ce44SJohn Forte 		break;
403*fcf3ce44SJohn Forte 	default:
404*fcf3ce44SJohn Forte 		lcp->type = 0; /* invalid */
405*fcf3ce44SJohn Forte 		ec = ISNS_RSP_MSG_FORMAT_ERROR;
406*fcf3ce44SJohn Forte 	}
407*fcf3ce44SJohn Forte 
408*fcf3ce44SJohn Forte 	return (ec);
409*fcf3ce44SJohn Forte }
410*fcf3ce44SJohn Forte 
411*fcf3ce44SJohn Forte /*
412*fcf3ce44SJohn Forte  * ****************************************************************************
413*fcf3ce44SJohn Forte  *
414*fcf3ce44SJohn Forte  * rsp_add_op:
415*fcf3ce44SJohn Forte  *	add the operating attributes to the response packet.
416*fcf3ce44SJohn Forte  *
417*fcf3ce44SJohn Forte  * conn	- the argument of the connection.
418*fcf3ce44SJohn Forte  * obj	- the object which is being added as operating attributes.
419*fcf3ce44SJohn Forte  * return - error code.
420*fcf3ce44SJohn Forte  *
421*fcf3ce44SJohn Forte  * ****************************************************************************
422*fcf3ce44SJohn Forte  */
423*fcf3ce44SJohn Forte static int
424*fcf3ce44SJohn Forte rsp_add_op(
425*fcf3ce44SJohn Forte 	conn_arg_t *conn,
426*fcf3ce44SJohn Forte 	isns_obj_t *obj
427*fcf3ce44SJohn Forte )
428*fcf3ce44SJohn Forte {
429*fcf3ce44SJohn Forte 	int ec = 0;
430*fcf3ce44SJohn Forte 
431*fcf3ce44SJohn Forte 	isns_attr_t *attr;
432*fcf3ce44SJohn Forte 	int i;
433*fcf3ce44SJohn Forte 
434*fcf3ce44SJohn Forte 	isns_pdu_t *rsp = conn->out_packet.pdu;
435*fcf3ce44SJohn Forte 	size_t pl = conn->out_packet.pl;
436*fcf3ce44SJohn Forte 	size_t sz = conn->out_packet.sz;
437*fcf3ce44SJohn Forte 
438*fcf3ce44SJohn Forte 	i = 0;
439*fcf3ce44SJohn Forte 	while (i < NUM_OF_ATTRS[obj->type] &&
440*fcf3ce44SJohn Forte 	    ec == 0) {
441*fcf3ce44SJohn Forte 		attr = &obj->attrs[i];
442*fcf3ce44SJohn Forte 		/* there is an attribute, send it back */
443*fcf3ce44SJohn Forte 		if (attr->tag != 0) {
444*fcf3ce44SJohn Forte 			ec = pdu_add_tlv(&rsp, &pl, &sz,
445*fcf3ce44SJohn Forte 			    attr->tag, attr->len,
446*fcf3ce44SJohn Forte 			    (void *)attr->value.ptr, 0);
447*fcf3ce44SJohn Forte 		}
448*fcf3ce44SJohn Forte 		i ++;
449*fcf3ce44SJohn Forte 	}
450*fcf3ce44SJohn Forte 
451*fcf3ce44SJohn Forte 	conn->out_packet.pdu = rsp;
452*fcf3ce44SJohn Forte 	conn->out_packet.pl = pl;
453*fcf3ce44SJohn Forte 	conn->out_packet.sz = sz;
454*fcf3ce44SJohn Forte 
455*fcf3ce44SJohn Forte 	return (ec);
456*fcf3ce44SJohn Forte }
457*fcf3ce44SJohn Forte 
458*fcf3ce44SJohn Forte /*
459*fcf3ce44SJohn Forte  * ****************************************************************************
460*fcf3ce44SJohn Forte  *
461*fcf3ce44SJohn Forte  * rsp_add_key:
462*fcf3ce44SJohn Forte  *	add the key attributes to the response packet.
463*fcf3ce44SJohn Forte  *
464*fcf3ce44SJohn Forte  * conn	- the argument of the connection.
465*fcf3ce44SJohn Forte  * entity - the object which is being added as key attributes.
466*fcf3ce44SJohn Forte  * return - error code.
467*fcf3ce44SJohn Forte  *
468*fcf3ce44SJohn Forte  * ****************************************************************************
469*fcf3ce44SJohn Forte  */
470*fcf3ce44SJohn Forte static int
471*fcf3ce44SJohn Forte rsp_add_key(
472*fcf3ce44SJohn Forte 	conn_arg_t *conn,
473*fcf3ce44SJohn Forte 	isns_obj_t *entity
474*fcf3ce44SJohn Forte )
475*fcf3ce44SJohn Forte {
476*fcf3ce44SJohn Forte 	int ec = 0;
477*fcf3ce44SJohn Forte 
478*fcf3ce44SJohn Forte 	isns_tlv_t *key = conn->in_packet.key;
479*fcf3ce44SJohn Forte 	size_t key_len = conn->in_packet.key_len;
480*fcf3ce44SJohn Forte 	uint32_t tag = ISNS_EID_ATTR_ID;
481*fcf3ce44SJohn Forte 	isns_attr_t *attr = &entity->attrs[ATTR_INDEX_ENTITY(tag)];
482*fcf3ce44SJohn Forte 	uint32_t len = attr->len;
483*fcf3ce44SJohn Forte 
484*fcf3ce44SJohn Forte 	isns_pdu_t *rsp = conn->out_packet.pdu;
485*fcf3ce44SJohn Forte 	size_t pl = conn->out_packet.pl;
486*fcf3ce44SJohn Forte 	size_t sz = conn->out_packet.sz;
487*fcf3ce44SJohn Forte 
488*fcf3ce44SJohn Forte 	if (key_len == 0) {
489*fcf3ce44SJohn Forte 		ec = pdu_add_tlv(&rsp, &pl, &sz,
490*fcf3ce44SJohn Forte 		    tag, len, (void *)attr->value.ptr, 0);
491*fcf3ce44SJohn Forte 	} else {
492*fcf3ce44SJohn Forte 		while (key_len >= 8 &&
493*fcf3ce44SJohn Forte 		    ec == 0) {
494*fcf3ce44SJohn Forte 			if (key->attr_id == ISNS_EID_ATTR_ID) {
495*fcf3ce44SJohn Forte 				ec = pdu_add_tlv(&rsp, &pl, &sz,
496*fcf3ce44SJohn Forte 				    tag, len,
497*fcf3ce44SJohn Forte 				    (void *)attr->value.ptr, 0);
498*fcf3ce44SJohn Forte 			} else {
499*fcf3ce44SJohn Forte 				ec = pdu_add_tlv(&rsp, &pl, &sz,
500*fcf3ce44SJohn Forte 				    key->attr_id, key->attr_len,
501*fcf3ce44SJohn Forte 				    (void *)key->attr_value, 1);
502*fcf3ce44SJohn Forte 			}
503*fcf3ce44SJohn Forte 			NEXT_TLV(key, key_len);
504*fcf3ce44SJohn Forte 		}
505*fcf3ce44SJohn Forte 	}
506*fcf3ce44SJohn Forte 
507*fcf3ce44SJohn Forte 	if (ec == 0) {
508*fcf3ce44SJohn Forte 		ec = pdu_add_tlv(&rsp, &pl, &sz,
509*fcf3ce44SJohn Forte 		    ISNS_DELIMITER_ATTR_ID, 0, NULL, 0);
510*fcf3ce44SJohn Forte 	}
511*fcf3ce44SJohn Forte 
512*fcf3ce44SJohn Forte 	conn->out_packet.pdu = rsp;
513*fcf3ce44SJohn Forte 	conn->out_packet.pl = pl;
514*fcf3ce44SJohn Forte 	conn->out_packet.sz = sz;
515*fcf3ce44SJohn Forte 
516*fcf3ce44SJohn Forte 	if (ec == 0) {
517*fcf3ce44SJohn Forte 		ec = rsp_add_op(conn, entity);
518*fcf3ce44SJohn Forte 	}
519*fcf3ce44SJohn Forte 
520*fcf3ce44SJohn Forte 	return (ec);
521*fcf3ce44SJohn Forte }
522*fcf3ce44SJohn Forte 
523*fcf3ce44SJohn Forte /*
524*fcf3ce44SJohn Forte  * ****************************************************************************
525*fcf3ce44SJohn Forte  *
526*fcf3ce44SJohn Forte  * rsp_add_tlv:
527*fcf3ce44SJohn Forte  *	add one attribute with TLV format to the response packet.
528*fcf3ce44SJohn Forte  *
529*fcf3ce44SJohn Forte  * conn	- the argument of the connection.
530*fcf3ce44SJohn Forte  * tag	- the tag of the attribute.
531*fcf3ce44SJohn Forte  * len	- the length of the attribute.
532*fcf3ce44SJohn Forte  * value- the value of the attribute.
533*fcf3ce44SJohn Forte  * pflag- the flag of the value, 0: value; 1: pointer to value
534*fcf3ce44SJohn Forte  * return - error code.
535*fcf3ce44SJohn Forte  *
536*fcf3ce44SJohn Forte  * ****************************************************************************
537*fcf3ce44SJohn Forte  */
538*fcf3ce44SJohn Forte static int
539*fcf3ce44SJohn Forte rsp_add_tlv(
540*fcf3ce44SJohn Forte 	conn_arg_t *conn,
541*fcf3ce44SJohn Forte 	uint32_t tag,
542*fcf3ce44SJohn Forte 	uint32_t len,
543*fcf3ce44SJohn Forte 	void *value,
544*fcf3ce44SJohn Forte 	int pflag
545*fcf3ce44SJohn Forte )
546*fcf3ce44SJohn Forte {
547*fcf3ce44SJohn Forte 	int ec = 0;
548*fcf3ce44SJohn Forte 
549*fcf3ce44SJohn Forte 	isns_pdu_t *rsp = conn->out_packet.pdu;
550*fcf3ce44SJohn Forte 	size_t pl = conn->out_packet.pl;
551*fcf3ce44SJohn Forte 	size_t sz = conn->out_packet.sz;
552*fcf3ce44SJohn Forte 
553*fcf3ce44SJohn Forte 	ec = pdu_add_tlv(&rsp, &pl, &sz, tag, len, value, pflag);
554*fcf3ce44SJohn Forte 
555*fcf3ce44SJohn Forte 	conn->out_packet.pdu = rsp;
556*fcf3ce44SJohn Forte 	conn->out_packet.pl = pl;
557*fcf3ce44SJohn Forte 	conn->out_packet.sz = sz;
558*fcf3ce44SJohn Forte 
559*fcf3ce44SJohn Forte 	return (ec);
560*fcf3ce44SJohn Forte }
561*fcf3ce44SJohn Forte 
562*fcf3ce44SJohn Forte /*
563*fcf3ce44SJohn Forte  * ****************************************************************************
564*fcf3ce44SJohn Forte  *
565*fcf3ce44SJohn Forte  * rsp_add_tlvs:
566*fcf3ce44SJohn Forte  *	add attributes with TLV format to the response packet.
567*fcf3ce44SJohn Forte  *
568*fcf3ce44SJohn Forte  * conn	- the argument of the connection.
569*fcf3ce44SJohn Forte  * tlv	- the attributes with TLV format being added.
570*fcf3ce44SJohn Forte  * tlv_len - the length of the attributes.
571*fcf3ce44SJohn Forte  * return - error code.
572*fcf3ce44SJohn Forte  *
573*fcf3ce44SJohn Forte  * ****************************************************************************
574*fcf3ce44SJohn Forte  */
575*fcf3ce44SJohn Forte static int
576*fcf3ce44SJohn Forte rsp_add_tlvs(
577*fcf3ce44SJohn Forte 	conn_arg_t *conn,
578*fcf3ce44SJohn Forte 	isns_tlv_t *tlv,
579*fcf3ce44SJohn Forte 	uint32_t tlv_len
580*fcf3ce44SJohn Forte )
581*fcf3ce44SJohn Forte {
582*fcf3ce44SJohn Forte 	int ec = 0;
583*fcf3ce44SJohn Forte 
584*fcf3ce44SJohn Forte 	uint32_t tag;
585*fcf3ce44SJohn Forte 	uint32_t len;
586*fcf3ce44SJohn Forte 	void *value;
587*fcf3ce44SJohn Forte 
588*fcf3ce44SJohn Forte 	while (tlv_len >= 8 &&
589*fcf3ce44SJohn Forte 	    ec == 0) {
590*fcf3ce44SJohn Forte 		tag = tlv->attr_id;
591*fcf3ce44SJohn Forte 		len = tlv->attr_len;
592*fcf3ce44SJohn Forte 		value = (void *)tlv->attr_value;
593*fcf3ce44SJohn Forte 
594*fcf3ce44SJohn Forte 		ec = rsp_add_tlv(conn, tag, len, value, 1);
595*fcf3ce44SJohn Forte 
596*fcf3ce44SJohn Forte 		NEXT_TLV(tlv, tlv_len);
597*fcf3ce44SJohn Forte 	}
598*fcf3ce44SJohn Forte 
599*fcf3ce44SJohn Forte 	return (ec);
600*fcf3ce44SJohn Forte }
601*fcf3ce44SJohn Forte 
602*fcf3ce44SJohn Forte /*
603*fcf3ce44SJohn Forte  * ****************************************************************************
604*fcf3ce44SJohn Forte  *
605*fcf3ce44SJohn Forte  * dev_attr_reg:
606*fcf3ce44SJohn Forte  *	function which handles the isnsp DEV_ATTR_REG message.
607*fcf3ce44SJohn Forte  *
608*fcf3ce44SJohn Forte  * conn	- the argument of the connection.
609*fcf3ce44SJohn Forte  * return - 0: the message requires response.
610*fcf3ce44SJohn Forte  *
611*fcf3ce44SJohn Forte  * ****************************************************************************
612*fcf3ce44SJohn Forte  */
613*fcf3ce44SJohn Forte static int
614*fcf3ce44SJohn Forte dev_attr_reg(
615*fcf3ce44SJohn Forte 	conn_arg_t *conn
616*fcf3ce44SJohn Forte )
617*fcf3ce44SJohn Forte {
618*fcf3ce44SJohn Forte 	int ec = 0;
619*fcf3ce44SJohn Forte 
620*fcf3ce44SJohn Forte 	isns_pdu_t *pdu = conn->in_packet.pdu;
621*fcf3ce44SJohn Forte 	isns_tlv_t *source = conn->in_packet.source;
622*fcf3ce44SJohn Forte 	isns_tlv_t *key = conn->in_packet.key;
623*fcf3ce44SJohn Forte 	uint16_t key_len = conn->in_packet.key_len;
624*fcf3ce44SJohn Forte 	isns_tlv_t *op = conn->in_packet.op;
625*fcf3ce44SJohn Forte 	uint16_t op_len = conn->in_packet.op_len;
626*fcf3ce44SJohn Forte 
627*fcf3ce44SJohn Forte 	boolean_t replace =
628*fcf3ce44SJohn Forte 	    ((pdu->flags & ISNS_FLAG_REPLACE_REG) == ISNS_FLAG_REPLACE_REG);
629*fcf3ce44SJohn Forte 
630*fcf3ce44SJohn Forte 	lookup_ctrl_t lc, lc_key;
631*fcf3ce44SJohn Forte 	uchar_t *iscsi_name;
632*fcf3ce44SJohn Forte 	int ctrl;
633*fcf3ce44SJohn Forte 
634*fcf3ce44SJohn Forte 	isns_obj_t *ety = NULL;	/* network entity object */
635*fcf3ce44SJohn Forte 	isns_type_t ptype;	/* parent object type */
636*fcf3ce44SJohn Forte 	uint32_t puid;		/* parent object UID */
637*fcf3ce44SJohn Forte 	void const **child[MAX_CHILD_TYPE] = { NULL };   /* children */
638*fcf3ce44SJohn Forte 	int ety_update, obj_update;
639*fcf3ce44SJohn Forte 	isns_attr_t *eid_attr;
640*fcf3ce44SJohn Forte 
641*fcf3ce44SJohn Forte 	isns_obj_t *obj;	/* child object */
642*fcf3ce44SJohn Forte 	isns_type_t ctype;	/* child object type */
643*fcf3ce44SJohn Forte 	uint32_t uid;		/* child object uid */
644*fcf3ce44SJohn Forte 	isns_attr_t pgt[3] = { NULL };
645*fcf3ce44SJohn Forte 
646*fcf3ce44SJohn Forte 	void const **vpp = NULL;
647*fcf3ce44SJohn Forte 	int i = 0;
648*fcf3ce44SJohn Forte 
649*fcf3ce44SJohn Forte 	isnslog(LOG_DEBUG, "dev_attr_reg", "entered (replace: %d)", replace);
650*fcf3ce44SJohn Forte 
651*fcf3ce44SJohn Forte 	ec = pdu_reset_rsp(&conn->out_packet.pdu,
652*fcf3ce44SJohn Forte 	    &conn->out_packet.pl,
653*fcf3ce44SJohn Forte 	    &conn->out_packet.sz);
654*fcf3ce44SJohn Forte 	if (ec != 0) {
655*fcf3ce44SJohn Forte 		goto reg_done;
656*fcf3ce44SJohn Forte 	}
657*fcf3ce44SJohn Forte 
658*fcf3ce44SJohn Forte 	iscsi_name = (uchar_t *)&source->attr_value[0];
659*fcf3ce44SJohn Forte 	ctrl = is_control_node(iscsi_name);
660*fcf3ce44SJohn Forte 	lc_key.type = 0;
661*fcf3ce44SJohn Forte 	if (key != NULL) {
662*fcf3ce44SJohn Forte 		/* validate key attributes and make lcp for */
663*fcf3ce44SJohn Forte 		/* the object identified by key attributes. */
664*fcf3ce44SJohn Forte 		ec = setup_key_lcp(&lc, key, key_len);
665*fcf3ce44SJohn Forte 		if (ec == 0 && lc.type != 0) {
666*fcf3ce44SJohn Forte 			lc_key = lc;
667*fcf3ce44SJohn Forte 			/* object is not found */
668*fcf3ce44SJohn Forte 			if ((uid = is_obj_there(&lc)) == 0) {
669*fcf3ce44SJohn Forte 				/* error if it is a network entity */
670*fcf3ce44SJohn Forte 				if (lc.type != OBJ_ENTITY) {
671*fcf3ce44SJohn Forte 					ec = ISNS_RSP_INVALID_REGIS;
672*fcf3ce44SJohn Forte 				}
673*fcf3ce44SJohn Forte 			/* validate for the source attribute before */
674*fcf3ce44SJohn Forte 			/* update or replace the network entity object */
675*fcf3ce44SJohn Forte 			} else if (ctrl == 0 &&
676*fcf3ce44SJohn Forte #ifndef SKIP_SRC_AUTH
677*fcf3ce44SJohn Forte 			    reg_auth_src(lc.type, uid, iscsi_name) == 0) {
678*fcf3ce44SJohn Forte #else
679*fcf3ce44SJohn Forte 			    0) {
680*fcf3ce44SJohn Forte #endif
681*fcf3ce44SJohn Forte 				ec = ISNS_RSP_SRC_UNAUTHORIZED;
682*fcf3ce44SJohn Forte 			/* de-register the network entity if replace is true */
683*fcf3ce44SJohn Forte 			} else if (replace != 0) {
684*fcf3ce44SJohn Forte 				UPDATE_LCP_UID(&lc, uid);
685*fcf3ce44SJohn Forte 				ec = dereg_object(&lc, 0);
686*fcf3ce44SJohn Forte 				/* generate a SCN */
687*fcf3ce44SJohn Forte 				if (ec == 0) {
688*fcf3ce44SJohn Forte 					(void) queue_msg_set(scn_q,
689*fcf3ce44SJohn Forte 					    SCN_TRIGGER, NULL);
690*fcf3ce44SJohn Forte 				}
691*fcf3ce44SJohn Forte 			}
692*fcf3ce44SJohn Forte 		}
693*fcf3ce44SJohn Forte 	}
694*fcf3ce44SJohn Forte 	if (ec != 0) {
695*fcf3ce44SJohn Forte 		goto reg_done;
696*fcf3ce44SJohn Forte 	}
697*fcf3ce44SJohn Forte 
698*fcf3ce44SJohn Forte 	/* register the network entity object */
699*fcf3ce44SJohn Forte 	ec = reg_get_entity(&ety, &op, &op_len);
700*fcf3ce44SJohn Forte 	if (ec != 0) {
701*fcf3ce44SJohn Forte 		goto reg_done;
702*fcf3ce44SJohn Forte 	}
703*fcf3ce44SJohn Forte 	if (ety == NULL && lc_key.type != OBJ_ENTITY) {
704*fcf3ce44SJohn Forte 		ety = make_default_entity();
705*fcf3ce44SJohn Forte 	} else if (ety == NULL ||
706*fcf3ce44SJohn Forte 	    (lc_key.type == OBJ_ENTITY &&
707*fcf3ce44SJohn Forte 	    key_cmp(&lc_key, ety) != 0)) {
708*fcf3ce44SJohn Forte 		/* the eid in key attribute and */
709*fcf3ce44SJohn Forte 		/* op attribute must be the same */
710*fcf3ce44SJohn Forte 		ec = ISNS_RSP_INVALID_REGIS;
711*fcf3ce44SJohn Forte 		goto reg_done;
712*fcf3ce44SJohn Forte 	}
713*fcf3ce44SJohn Forte 	if (ety == NULL || rsp_add_key(conn, ety) != 0) {
714*fcf3ce44SJohn Forte 		ec = ISNS_RSP_INTERNAL_ERROR;
715*fcf3ce44SJohn Forte 	} else {
716*fcf3ce44SJohn Forte 		eid_attr = &ety->attrs[ATTR_INDEX_ENTITY(ISNS_EID_ATTR_ID)];
717*fcf3ce44SJohn Forte 		ec = register_object(ety, &puid, &ety_update);
718*fcf3ce44SJohn Forte 		ptype = OBJ_ENTITY;
719*fcf3ce44SJohn Forte 	}
720*fcf3ce44SJohn Forte 	if (ec == 0 && ety_update == 0) {
721*fcf3ce44SJohn Forte 		/* newly registered, reset the pointer */
722*fcf3ce44SJohn Forte 		ety = NULL;
723*fcf3ce44SJohn Forte 	}
724*fcf3ce44SJohn Forte 
725*fcf3ce44SJohn Forte 	/* register the reset of objects which are specified in */
726*fcf3ce44SJohn Forte 	/* operating attributes */
727*fcf3ce44SJohn Forte 	while (ec == 0 &&
728*fcf3ce44SJohn Forte 	    (ec = reg_get_obj(&obj, &pgt[0], &op, &op_len)) == 0 &&
729*fcf3ce44SJohn Forte 	    obj != NULL &&
730*fcf3ce44SJohn Forte 	    (ec = rsp_add_op(conn, obj)) == 0) {
731*fcf3ce44SJohn Forte 		ctype = obj->type;
732*fcf3ce44SJohn Forte 		/* set the parent object UID */
733*fcf3ce44SJohn Forte 		(void) set_parent_obj(obj, puid);
734*fcf3ce44SJohn Forte 		/* register it */
735*fcf3ce44SJohn Forte 		ec = register_object(obj, &uid, &obj_update);
736*fcf3ce44SJohn Forte 		if (ec == 0) {
737*fcf3ce44SJohn Forte 			if (obj_update == 0 ||
738*fcf3ce44SJohn Forte 			    is_obj_online(obj) == 0) {
739*fcf3ce44SJohn Forte 				/* update the ref'd object */
740*fcf3ce44SJohn Forte 				(void) update_ref_obj(obj);
741*fcf3ce44SJohn Forte 				/* add the newly registered object info */
742*fcf3ce44SJohn Forte 				/* to child info array of the parent object */
743*fcf3ce44SJohn Forte 				ec = buff_child_obj(ptype, ctype, obj, child);
744*fcf3ce44SJohn Forte 			} else {
745*fcf3ce44SJohn Forte 				if (ctrl == 0 &&
746*fcf3ce44SJohn Forte #ifndef SKIP_SRC_AUTH
747*fcf3ce44SJohn Forte 				    puid != get_parent_uid(obj)) {
748*fcf3ce44SJohn Forte #else
749*fcf3ce44SJohn Forte 				    0) {
750*fcf3ce44SJohn Forte #endif
751*fcf3ce44SJohn Forte 					ec = ISNS_RSP_SRC_UNAUTHORIZED;
752*fcf3ce44SJohn Forte 				}
753*fcf3ce44SJohn Forte 				/* it was for updating an existing object */
754*fcf3ce44SJohn Forte 				free_one_object(obj);
755*fcf3ce44SJohn Forte 			}
756*fcf3ce44SJohn Forte 		} else {
757*fcf3ce44SJohn Forte 			/* failed registering it */
758*fcf3ce44SJohn Forte 			free_one_object(obj);
759*fcf3ce44SJohn Forte 		}
760*fcf3ce44SJohn Forte 	}
761*fcf3ce44SJohn Forte 
762*fcf3ce44SJohn Forte 	/* update the portal group object for the associations between */
763*fcf3ce44SJohn Forte 	/* the newly registered objects and previously registered objects */
764*fcf3ce44SJohn Forte 	if (ec == 0) {
765*fcf3ce44SJohn Forte 		ec = verify_ref_obj(ptype, puid, child);
766*fcf3ce44SJohn Forte 	}
767*fcf3ce44SJohn Forte 	if (ec != 0) {
768*fcf3ce44SJohn Forte 		goto reg_done;
769*fcf3ce44SJohn Forte 	}
770*fcf3ce44SJohn Forte 
771*fcf3ce44SJohn Forte 	/* update the children list of the parent object */
772*fcf3ce44SJohn Forte 	while (i < MAX_CHILD_TYPE) {
773*fcf3ce44SJohn Forte 		vpp = child[i];
774*fcf3ce44SJohn Forte 		if (vpp != NULL) {
775*fcf3ce44SJohn Forte 			break;
776*fcf3ce44SJohn Forte 		}
777*fcf3ce44SJohn Forte 		i ++;
778*fcf3ce44SJohn Forte 	}
779*fcf3ce44SJohn Forte 	if (vpp != NULL) {
780*fcf3ce44SJohn Forte 		ec = update_child_obj(ptype, puid, child, 1);
781*fcf3ce44SJohn Forte 	} else {
782*fcf3ce44SJohn Forte #ifndef SKIP_SRC_AUTH
783*fcf3ce44SJohn Forte 		ec = ISNS_RSP_INVALID_REGIS;
784*fcf3ce44SJohn Forte #else
785*fcf3ce44SJohn Forte 		/* for interop-ability, we cannot treat this as */
786*fcf3ce44SJohn Forte 		/* an error, instead, remove the network entity */
787*fcf3ce44SJohn Forte 		SET_UID_LCP(&lc, OBJ_ENTITY, puid);
788*fcf3ce44SJohn Forte 		ec = dereg_object(&lc, 0);
789*fcf3ce44SJohn Forte 		goto reg_done;
790*fcf3ce44SJohn Forte #endif
791*fcf3ce44SJohn Forte 	}
792*fcf3ce44SJohn Forte 	if (ec != 0) {
793*fcf3ce44SJohn Forte 		goto reg_done;
794*fcf3ce44SJohn Forte 	}
795*fcf3ce44SJohn Forte 	/* add esi entry */
796*fcf3ce44SJohn Forte 	if (ety_update != 0) {
797*fcf3ce44SJohn Forte 		(void) esi_remove(puid);
798*fcf3ce44SJohn Forte 	}
799*fcf3ce44SJohn Forte 	ec = esi_add(puid, eid_attr->value.ptr, eid_attr->len);
800*fcf3ce44SJohn Forte 
801*fcf3ce44SJohn Forte reg_done:
802*fcf3ce44SJohn Forte 	conn->ec = ec;
803*fcf3ce44SJohn Forte 	free_one_object(ety);
804*fcf3ce44SJohn Forte 	uid = 0;
805*fcf3ce44SJohn Forte 	while (uid < MAX_CHILD_TYPE) {
806*fcf3ce44SJohn Forte 		if (child[uid] != NULL) {
807*fcf3ce44SJohn Forte 			free(child[uid]);
808*fcf3ce44SJohn Forte 		}
809*fcf3ce44SJohn Forte 		uid ++;
810*fcf3ce44SJohn Forte 	}
811*fcf3ce44SJohn Forte 
812*fcf3ce44SJohn Forte 	if (ec != 0) {
813*fcf3ce44SJohn Forte 		isnslog(LOG_DEBUG, "dev_attr_reg", "error code: %d", ec);
814*fcf3ce44SJohn Forte 	}
815*fcf3ce44SJohn Forte 
816*fcf3ce44SJohn Forte 	return (0);
817*fcf3ce44SJohn Forte }
818*fcf3ce44SJohn Forte 
819*fcf3ce44SJohn Forte /*
820*fcf3ce44SJohn Forte  * ****************************************************************************
821*fcf3ce44SJohn Forte  *
822*fcf3ce44SJohn Forte  * dev_attr_qry:
823*fcf3ce44SJohn Forte  *	function which handles the isnsp DEV_ATTR_QRY message.
824*fcf3ce44SJohn Forte  *
825*fcf3ce44SJohn Forte  * conn	- the argument of the connection.
826*fcf3ce44SJohn Forte  * return - 0: the message requires response.
827*fcf3ce44SJohn Forte  *
828*fcf3ce44SJohn Forte  * ****************************************************************************
829*fcf3ce44SJohn Forte  */
830*fcf3ce44SJohn Forte static int
831*fcf3ce44SJohn Forte dev_attr_qry(
832*fcf3ce44SJohn Forte 	conn_arg_t *conn
833*fcf3ce44SJohn Forte )
834*fcf3ce44SJohn Forte {
835*fcf3ce44SJohn Forte 	int ec = 0;
836*fcf3ce44SJohn Forte 
837*fcf3ce44SJohn Forte 	/* isns_pdu_t *pdu = conn->in_packet.pdu; */
838*fcf3ce44SJohn Forte 	isns_tlv_t *source = conn->in_packet.source;
839*fcf3ce44SJohn Forte 	isns_tlv_t *key = conn->in_packet.key;
840*fcf3ce44SJohn Forte 	uint16_t key_len = conn->in_packet.key_len;
841*fcf3ce44SJohn Forte 	isns_tlv_t *op = conn->in_packet.op;
842*fcf3ce44SJohn Forte 	uint16_t op_len = conn->in_packet.op_len;
843*fcf3ce44SJohn Forte 
844*fcf3ce44SJohn Forte 	uchar_t *iscsi_name;
845*fcf3ce44SJohn Forte 
846*fcf3ce44SJohn Forte 	bmp_t *nodes_bmp = NULL;
847*fcf3ce44SJohn Forte 	uint32_t num_of_nodes;
848*fcf3ce44SJohn Forte 	uint32_t *key_uids = NULL;
849*fcf3ce44SJohn Forte 	uint32_t num_of_keys;
850*fcf3ce44SJohn Forte 	isns_type_t key_type;
851*fcf3ce44SJohn Forte 
852*fcf3ce44SJohn Forte 	uint32_t key_uid;
853*fcf3ce44SJohn Forte 	uint32_t op_uid;
854*fcf3ce44SJohn Forte 
855*fcf3ce44SJohn Forte 	uint32_t size_of_ops;
856*fcf3ce44SJohn Forte 	uint32_t num_of_ops;
857*fcf3ce44SJohn Forte 	uint32_t *op_uids = NULL;
858*fcf3ce44SJohn Forte 	isns_type_t op_type;
859*fcf3ce44SJohn Forte 
860*fcf3ce44SJohn Forte 	isns_tlv_t *tlv;
861*fcf3ce44SJohn Forte 	uint16_t tlv_len;
862*fcf3ce44SJohn Forte 
863*fcf3ce44SJohn Forte 	isnslog(LOG_DEBUG, "dev_attr_qry", "entered");
864*fcf3ce44SJohn Forte 
865*fcf3ce44SJohn Forte 	ec = pdu_reset_rsp(&conn->out_packet.pdu,
866*fcf3ce44SJohn Forte 	    &conn->out_packet.pl,
867*fcf3ce44SJohn Forte 	    &conn->out_packet.sz);
868*fcf3ce44SJohn Forte 	if (ec != 0) {
869*fcf3ce44SJohn Forte 		goto qry_done;
870*fcf3ce44SJohn Forte 	}
871*fcf3ce44SJohn Forte 
872*fcf3ce44SJohn Forte 	/*
873*fcf3ce44SJohn Forte 	 * RFC 4171 section 5.7.5.2:
874*fcf3ce44SJohn Forte 	 * If no Operating Attributes are included in the original query, then
875*fcf3ce44SJohn Forte 	 * all Operating Attributes SHALL be returned in the response. ???
876*fcf3ce44SJohn Forte 	 */
877*fcf3ce44SJohn Forte 	if (op_len == 0) {
878*fcf3ce44SJohn Forte 		goto qry_done;
879*fcf3ce44SJohn Forte 	}
880*fcf3ce44SJohn Forte 
881*fcf3ce44SJohn Forte 	iscsi_name = (uchar_t *)&source->attr_value[0];
882*fcf3ce44SJohn Forte 	if (is_control_node(iscsi_name) == 0) {
883*fcf3ce44SJohn Forte 		ec = get_scope(iscsi_name, &nodes_bmp, &num_of_nodes);
884*fcf3ce44SJohn Forte 		if (ec != 0 || nodes_bmp == NULL) {
885*fcf3ce44SJohn Forte 			goto qry_done;
886*fcf3ce44SJohn Forte 		}
887*fcf3ce44SJohn Forte 	}
888*fcf3ce44SJohn Forte 
889*fcf3ce44SJohn Forte 	size_of_ops = 0;
890*fcf3ce44SJohn Forte 	if (key != NULL) {
891*fcf3ce44SJohn Forte 		/*
892*fcf3ce44SJohn Forte 		 * Return the original message key.
893*fcf3ce44SJohn Forte 		 */
894*fcf3ce44SJohn Forte 		ec = rsp_add_tlvs(conn, key, key_len);
895*fcf3ce44SJohn Forte 		if (ec != 0) {
896*fcf3ce44SJohn Forte 			goto qry_done;
897*fcf3ce44SJohn Forte 		}
898*fcf3ce44SJohn Forte 
899*fcf3ce44SJohn Forte 		/*
900*fcf3ce44SJohn Forte 		 * Delimiter
901*fcf3ce44SJohn Forte 		 */
902*fcf3ce44SJohn Forte 		ec = rsp_add_tlv(conn, ISNS_DELIMITER_ATTR_ID, 0, NULL, 0);
903*fcf3ce44SJohn Forte 		if (ec != 0) {
904*fcf3ce44SJohn Forte 			goto qry_done;
905*fcf3ce44SJohn Forte 		}
906*fcf3ce44SJohn Forte 
907*fcf3ce44SJohn Forte 		/*
908*fcf3ce44SJohn Forte 		 * Query objects which match the Key Attributes.
909*fcf3ce44SJohn Forte 		 */
910*fcf3ce44SJohn Forte 		ec = get_qry_keys(nodes_bmp, num_of_nodes, &key_type,
911*fcf3ce44SJohn Forte 		    key, key_len, &key_uids, &num_of_keys);
912*fcf3ce44SJohn Forte 		if (ec != 0 || key_uids == NULL) {
913*fcf3ce44SJohn Forte 			goto qry_done;
914*fcf3ce44SJohn Forte 		}
915*fcf3ce44SJohn Forte 
916*fcf3ce44SJohn Forte 		/*
917*fcf3ce44SJohn Forte 		 * Iterate thru each object identified by the message key.
918*fcf3ce44SJohn Forte 		 */
919*fcf3ce44SJohn Forte 		tlv = op;
920*fcf3ce44SJohn Forte 		tlv_len = op_len;
921*fcf3ce44SJohn Forte 		FOR_EACH_OBJS(key_uids, num_of_keys, key_uid, {
922*fcf3ce44SJohn Forte 			/*
923*fcf3ce44SJohn Forte 			 * Iterate thru each Operating Attributes.
924*fcf3ce44SJohn Forte 			 */
925*fcf3ce44SJohn Forte 			op = tlv;
926*fcf3ce44SJohn Forte 			op_len = tlv_len;
927*fcf3ce44SJohn Forte 			FOR_EACH_OP(op, op_len, op_type, {
928*fcf3ce44SJohn Forte 				if (op_type == 0) {
929*fcf3ce44SJohn Forte 					ec = ISNS_RSP_INVALID_QRY;
930*fcf3ce44SJohn Forte 					goto qry_done;
931*fcf3ce44SJohn Forte 				}
932*fcf3ce44SJohn Forte 				ec = get_qry_ops(key_uid, key_type,
933*fcf3ce44SJohn Forte 				    op_type, &op_uids,
934*fcf3ce44SJohn Forte 				    &num_of_ops, &size_of_ops);
935*fcf3ce44SJohn Forte 				if (ec != 0) {
936*fcf3ce44SJohn Forte 					goto qry_done;
937*fcf3ce44SJohn Forte 				}
938*fcf3ce44SJohn Forte 				/*
939*fcf3ce44SJohn Forte 				 * Iterate thru each object for the Operating
940*fcf3ce44SJohn Forte 				 * Attributes again.
941*fcf3ce44SJohn Forte 				 */
942*fcf3ce44SJohn Forte 				FOR_EACH_OBJS(op_uids, num_of_ops, op_uid, {
943*fcf3ce44SJohn Forte 					ec = get_qry_attrs(op_uid, op_type,
944*fcf3ce44SJohn Forte 					    op, op_len, conn);
945*fcf3ce44SJohn Forte 					if (ec != 0) {
946*fcf3ce44SJohn Forte 						goto qry_done;
947*fcf3ce44SJohn Forte 					}
948*fcf3ce44SJohn Forte 				});
949*fcf3ce44SJohn Forte 			});
950*fcf3ce44SJohn Forte 		});
951*fcf3ce44SJohn Forte 	} else {
952*fcf3ce44SJohn Forte 		/*
953*fcf3ce44SJohn Forte 		 * Iterate thru each Operating Attributes.
954*fcf3ce44SJohn Forte 		 */
955*fcf3ce44SJohn Forte 		FOR_EACH_OP(op, op_len, op_type, {
956*fcf3ce44SJohn Forte 			ec = get_qry_ops2(nodes_bmp, num_of_nodes,
957*fcf3ce44SJohn Forte 			    op_type, &op_uids,
958*fcf3ce44SJohn Forte 			    &num_of_ops, &size_of_ops);
959*fcf3ce44SJohn Forte 			if (ec != 0) {
960*fcf3ce44SJohn Forte 				goto qry_done;
961*fcf3ce44SJohn Forte 			}
962*fcf3ce44SJohn Forte 			/*
963*fcf3ce44SJohn Forte 			 * Iterate thru each object for the Operating
964*fcf3ce44SJohn Forte 			 * Attributes again.
965*fcf3ce44SJohn Forte 			 */
966*fcf3ce44SJohn Forte 			FOR_EACH_OBJS(op_uids, num_of_ops, op_uid, {
967*fcf3ce44SJohn Forte 				ec = get_qry_attrs(op_uid, op_type,
968*fcf3ce44SJohn Forte 				    op, op_len, conn);
969*fcf3ce44SJohn Forte 				if (ec != 0) {
970*fcf3ce44SJohn Forte 					goto qry_done;
971*fcf3ce44SJohn Forte 				}
972*fcf3ce44SJohn Forte 			});
973*fcf3ce44SJohn Forte 		});
974*fcf3ce44SJohn Forte 	}
975*fcf3ce44SJohn Forte 
976*fcf3ce44SJohn Forte qry_done:
977*fcf3ce44SJohn Forte 	conn->ec = ec;
978*fcf3ce44SJohn Forte 
979*fcf3ce44SJohn Forte 	if (ec != 0) {
980*fcf3ce44SJohn Forte 		isnslog(LOG_DEBUG, "dev_attr_qry", "error code: %d", ec);
981*fcf3ce44SJohn Forte 	}
982*fcf3ce44SJohn Forte 
983*fcf3ce44SJohn Forte 	free(nodes_bmp);
984*fcf3ce44SJohn Forte 	free(key_uids);
985*fcf3ce44SJohn Forte 	free(op_uids);
986*fcf3ce44SJohn Forte 
987*fcf3ce44SJohn Forte 	return (0);
988*fcf3ce44SJohn Forte }
989*fcf3ce44SJohn Forte 
990*fcf3ce44SJohn Forte /*
991*fcf3ce44SJohn Forte  * ****************************************************************************
992*fcf3ce44SJohn Forte  *
993*fcf3ce44SJohn Forte  * dev_get_next:
994*fcf3ce44SJohn Forte  *	function which handles the isnsp DEV_GET_NEXT message.
995*fcf3ce44SJohn Forte  *
996*fcf3ce44SJohn Forte  * conn	- the argument of the connection.
997*fcf3ce44SJohn Forte  * return - 0: the message requires response.
998*fcf3ce44SJohn Forte  *
999*fcf3ce44SJohn Forte  * ****************************************************************************
1000*fcf3ce44SJohn Forte  */
1001*fcf3ce44SJohn Forte static int
1002*fcf3ce44SJohn Forte dev_get_next(
1003*fcf3ce44SJohn Forte 	conn_arg_t *conn
1004*fcf3ce44SJohn Forte )
1005*fcf3ce44SJohn Forte {
1006*fcf3ce44SJohn Forte 	int ec = 0;
1007*fcf3ce44SJohn Forte 
1008*fcf3ce44SJohn Forte 	/* isns_pdu_t *pdu = conn->in_packet.pdu; */
1009*fcf3ce44SJohn Forte 	isns_tlv_t *source = conn->in_packet.source;
1010*fcf3ce44SJohn Forte 	isns_tlv_t *key = conn->in_packet.key;
1011*fcf3ce44SJohn Forte 	uint16_t key_len = conn->in_packet.key_len;
1012*fcf3ce44SJohn Forte 	isns_tlv_t *op = conn->in_packet.op;
1013*fcf3ce44SJohn Forte 	uint16_t op_len = conn->in_packet.op_len;
1014*fcf3ce44SJohn Forte 
1015*fcf3ce44SJohn Forte 	uchar_t *iscsi_name;
1016*fcf3ce44SJohn Forte 
1017*fcf3ce44SJohn Forte 	bmp_t *nodes_bmp = NULL;
1018*fcf3ce44SJohn Forte 	uint32_t num_of_nodes;
1019*fcf3ce44SJohn Forte 
1020*fcf3ce44SJohn Forte 	isns_type_t key_type;
1021*fcf3ce44SJohn Forte 	isns_type_t op_type;
1022*fcf3ce44SJohn Forte 	uint32_t size_of_obj;
1023*fcf3ce44SJohn Forte 	uint32_t num_of_obj;
1024*fcf3ce44SJohn Forte 	uint32_t *obj_uids = NULL;
1025*fcf3ce44SJohn Forte 
1026*fcf3ce44SJohn Forte 	uint32_t uid;
1027*fcf3ce44SJohn Forte 
1028*fcf3ce44SJohn Forte 	isnslog(LOG_DEBUG, "dev_get_next", "entered");
1029*fcf3ce44SJohn Forte 
1030*fcf3ce44SJohn Forte 	ec = pdu_reset_rsp(&conn->out_packet.pdu,
1031*fcf3ce44SJohn Forte 	    &conn->out_packet.pl,
1032*fcf3ce44SJohn Forte 	    &conn->out_packet.sz);
1033*fcf3ce44SJohn Forte 	if (ec != 0) {
1034*fcf3ce44SJohn Forte 		goto get_next_done;
1035*fcf3ce44SJohn Forte 	}
1036*fcf3ce44SJohn Forte 
1037*fcf3ce44SJohn Forte 	iscsi_name = (uchar_t *)&source->attr_value[0];
1038*fcf3ce44SJohn Forte 	if (is_control_node(iscsi_name) == 0) {
1039*fcf3ce44SJohn Forte 		ec = get_scope(iscsi_name, &nodes_bmp, &num_of_nodes);
1040*fcf3ce44SJohn Forte 		if (nodes_bmp == NULL) {
1041*fcf3ce44SJohn Forte 			ec = ISNS_RSP_NO_SUCH_ENTRY;
1042*fcf3ce44SJohn Forte 		}
1043*fcf3ce44SJohn Forte 		if (ec != 0) {
1044*fcf3ce44SJohn Forte 			goto get_next_done;
1045*fcf3ce44SJohn Forte 		}
1046*fcf3ce44SJohn Forte 	}
1047*fcf3ce44SJohn Forte 
1048*fcf3ce44SJohn Forte 	/*
1049*fcf3ce44SJohn Forte 	 * Get Message Key type and validate the Message Key.
1050*fcf3ce44SJohn Forte 	 */
1051*fcf3ce44SJohn Forte 	key_type = TLV2TYPE(key);
1052*fcf3ce44SJohn Forte 	if (key_type == 0) {
1053*fcf3ce44SJohn Forte 		ec = ISNS_RSP_MSG_FORMAT_ERROR;
1054*fcf3ce44SJohn Forte 		goto get_next_done;
1055*fcf3ce44SJohn Forte 	}
1056*fcf3ce44SJohn Forte 	ec = validate_qry_key(key_type, key, key_len, NULL);
1057*fcf3ce44SJohn Forte 	if (ec != 0) {
1058*fcf3ce44SJohn Forte 		goto get_next_done;
1059*fcf3ce44SJohn Forte 	}
1060*fcf3ce44SJohn Forte 
1061*fcf3ce44SJohn Forte 	size_of_obj = 0;
1062*fcf3ce44SJohn Forte 	if (op != NULL) {
1063*fcf3ce44SJohn Forte 		/*
1064*fcf3ce44SJohn Forte 		 * Query the objects which match the Operating Attributes.
1065*fcf3ce44SJohn Forte 		 */
1066*fcf3ce44SJohn Forte 		ec = get_qry_keys(nodes_bmp, num_of_nodes, &op_type,
1067*fcf3ce44SJohn Forte 		    op, op_len, &obj_uids, &num_of_obj);
1068*fcf3ce44SJohn Forte 		if (op_type != key_type) {
1069*fcf3ce44SJohn Forte 			ec = ISNS_RSP_MSG_FORMAT_ERROR;
1070*fcf3ce44SJohn Forte 		}
1071*fcf3ce44SJohn Forte 	} else {
1072*fcf3ce44SJohn Forte 		/*
1073*fcf3ce44SJohn Forte 		 * Query the objects which match the Message Key type.
1074*fcf3ce44SJohn Forte 		 */
1075*fcf3ce44SJohn Forte 		ec = get_qry_ops2(nodes_bmp, num_of_nodes,
1076*fcf3ce44SJohn Forte 		    key_type, &obj_uids, &num_of_obj, &size_of_obj);
1077*fcf3ce44SJohn Forte 	}
1078*fcf3ce44SJohn Forte 	if (ec != 0) {
1079*fcf3ce44SJohn Forte 		goto get_next_done;
1080*fcf3ce44SJohn Forte 	}
1081*fcf3ce44SJohn Forte 
1082*fcf3ce44SJohn Forte 	/*
1083*fcf3ce44SJohn Forte 	 * Get the object which is next to the one indicated by the
1084*fcf3ce44SJohn Forte 	 * Message Key.
1085*fcf3ce44SJohn Forte 	 */
1086*fcf3ce44SJohn Forte 	uid = get_next_obj(key, key_len, key_type, obj_uids, num_of_obj);
1087*fcf3ce44SJohn Forte 	if (uid == 0) {
1088*fcf3ce44SJohn Forte 		ec = ISNS_RSP_NO_SUCH_ENTRY;
1089*fcf3ce44SJohn Forte 		goto get_next_done;
1090*fcf3ce44SJohn Forte 	}
1091*fcf3ce44SJohn Forte 
1092*fcf3ce44SJohn Forte 	/*
1093*fcf3ce44SJohn Forte 	 * Message Key
1094*fcf3ce44SJohn Forte 	 */
1095*fcf3ce44SJohn Forte 	if ((ec = get_qry_attrs1(uid, key_type, key, key_len, conn)) != 0) {
1096*fcf3ce44SJohn Forte 		goto get_next_done;
1097*fcf3ce44SJohn Forte 	}
1098*fcf3ce44SJohn Forte 
1099*fcf3ce44SJohn Forte 	/*
1100*fcf3ce44SJohn Forte 	 * Delimiter
1101*fcf3ce44SJohn Forte 	 */
1102*fcf3ce44SJohn Forte 	if ((ec = rsp_add_tlv(conn, ISNS_DELIMITER_ATTR_ID, 0, NULL, 0)) != 0) {
1103*fcf3ce44SJohn Forte 		goto get_next_done;
1104*fcf3ce44SJohn Forte 	}
1105*fcf3ce44SJohn Forte 
1106*fcf3ce44SJohn Forte 	/*
1107*fcf3ce44SJohn Forte 	 * Operating Attributes
1108*fcf3ce44SJohn Forte 	 */
1109*fcf3ce44SJohn Forte 	if (op != NULL) {
1110*fcf3ce44SJohn Forte 		ec = get_qry_attrs(uid, op_type, op, op_len, conn);
1111*fcf3ce44SJohn Forte 	}
1112*fcf3ce44SJohn Forte 
1113*fcf3ce44SJohn Forte get_next_done:
1114*fcf3ce44SJohn Forte 	conn->ec = ec;
1115*fcf3ce44SJohn Forte 
1116*fcf3ce44SJohn Forte 	if (ec != 0 && ec != ISNS_RSP_NO_SUCH_ENTRY) {
1117*fcf3ce44SJohn Forte 		isnslog(LOG_DEBUG, "dev_get_next", "error code: %d", ec);
1118*fcf3ce44SJohn Forte 	}
1119*fcf3ce44SJohn Forte 
1120*fcf3ce44SJohn Forte 	free(nodes_bmp);
1121*fcf3ce44SJohn Forte 	free(obj_uids);
1122*fcf3ce44SJohn Forte 
1123*fcf3ce44SJohn Forte 	return (0);
1124*fcf3ce44SJohn Forte }
1125*fcf3ce44SJohn Forte 
1126*fcf3ce44SJohn Forte /*
1127*fcf3ce44SJohn Forte  * ****************************************************************************
1128*fcf3ce44SJohn Forte  *
1129*fcf3ce44SJohn Forte  * dev_dereg:
1130*fcf3ce44SJohn Forte  *	function which handles the isnsp DEV_DEREG message.
1131*fcf3ce44SJohn Forte  *
1132*fcf3ce44SJohn Forte  * conn	- the argument of the connection.
1133*fcf3ce44SJohn Forte  * return - 0: the message requires response.
1134*fcf3ce44SJohn Forte  *
1135*fcf3ce44SJohn Forte  * ****************************************************************************
1136*fcf3ce44SJohn Forte  */
1137*fcf3ce44SJohn Forte static int
1138*fcf3ce44SJohn Forte dev_dereg(
1139*fcf3ce44SJohn Forte 	conn_arg_t *conn
1140*fcf3ce44SJohn Forte )
1141*fcf3ce44SJohn Forte {
1142*fcf3ce44SJohn Forte 	int ec = 0;
1143*fcf3ce44SJohn Forte 
1144*fcf3ce44SJohn Forte 	/* isns_pdu_t *pdu = conn->in_packet.pdu; */
1145*fcf3ce44SJohn Forte 	isns_tlv_t *source = conn->in_packet.source;
1146*fcf3ce44SJohn Forte 	/* isns_tlv_t *key = conn->in_packet.key; */
1147*fcf3ce44SJohn Forte 	/* uint16_t key_len = conn->in_packet.key_len; */
1148*fcf3ce44SJohn Forte 	isns_tlv_t *op = conn->in_packet.op;
1149*fcf3ce44SJohn Forte 	uint16_t op_len = conn->in_packet.op_len;
1150*fcf3ce44SJohn Forte 
1151*fcf3ce44SJohn Forte 	uchar_t *iscsi_name;
1152*fcf3ce44SJohn Forte 	int ctrl;
1153*fcf3ce44SJohn Forte 	uint32_t puid;
1154*fcf3ce44SJohn Forte 
1155*fcf3ce44SJohn Forte 	lookup_ctrl_t lc;
1156*fcf3ce44SJohn Forte 	uint8_t *value;
1157*fcf3ce44SJohn Forte 
1158*fcf3ce44SJohn Forte 	isnslog(LOG_DEBUG, "dev_dereg", "entered");
1159*fcf3ce44SJohn Forte 
1160*fcf3ce44SJohn Forte 	iscsi_name = (uchar_t *)&source->attr_value[0];
1161*fcf3ce44SJohn Forte 	ctrl = is_control_node(iscsi_name);
1162*fcf3ce44SJohn Forte 	if (ctrl == 0) {
1163*fcf3ce44SJohn Forte 		puid = is_parent_there(iscsi_name);
1164*fcf3ce44SJohn Forte 	}
1165*fcf3ce44SJohn Forte 
1166*fcf3ce44SJohn Forte 	while (op_len > 8 && ec == 0) {
1167*fcf3ce44SJohn Forte 		lc.curr_uid = 0;
1168*fcf3ce44SJohn Forte 		value = &op->attr_value[0];
1169*fcf3ce44SJohn Forte 		switch (op->attr_id) {
1170*fcf3ce44SJohn Forte 		case ISNS_EID_ATTR_ID:
1171*fcf3ce44SJohn Forte 			lc.id[0] = ATTR_INDEX_ENTITY(ISNS_EID_ATTR_ID);
1172*fcf3ce44SJohn Forte 			lc.op[0] = OP_STRING;
1173*fcf3ce44SJohn Forte 			lc.data[0].ptr = (uchar_t *)value;
1174*fcf3ce44SJohn Forte 			lc.op[1] = 0;
1175*fcf3ce44SJohn Forte 			lc.type = OBJ_ENTITY;
1176*fcf3ce44SJohn Forte 			break;
1177*fcf3ce44SJohn Forte 		case ISNS_ISCSI_NAME_ATTR_ID:
1178*fcf3ce44SJohn Forte 			lc.id[0] = ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID);
1179*fcf3ce44SJohn Forte 			lc.op[0] = OP_STRING;
1180*fcf3ce44SJohn Forte 			lc.data[0].ptr = (uchar_t *)value;
1181*fcf3ce44SJohn Forte 			lc.op[1] = 0;
1182*fcf3ce44SJohn Forte 			lc.type = OBJ_ISCSI;
1183*fcf3ce44SJohn Forte 			break;
1184*fcf3ce44SJohn Forte 		case ISNS_ISCSI_NODE_INDEX_ATTR_ID:
1185*fcf3ce44SJohn Forte 			lc.id[0] = ATTR_INDEX_ISCSI(
1186*fcf3ce44SJohn Forte 			    ISNS_ISCSI_NODE_INDEX_ATTR_ID);
1187*fcf3ce44SJohn Forte 			lc.op[0] = OP_INTEGER;
1188*fcf3ce44SJohn Forte 			lc.data[0].ui = ntohl(*(uint32_t *)value);
1189*fcf3ce44SJohn Forte 			lc.op[1] = 0;
1190*fcf3ce44SJohn Forte 			lc.type = OBJ_ISCSI;
1191*fcf3ce44SJohn Forte 			break;
1192*fcf3ce44SJohn Forte 		case ISNS_PORTAL_IP_ADDR_ATTR_ID:
1193*fcf3ce44SJohn Forte 			lc.id[0] = ATTR_INDEX_PORTAL(
1194*fcf3ce44SJohn Forte 			    ISNS_PORTAL_IP_ADDR_ATTR_ID);
1195*fcf3ce44SJohn Forte 			lc.op[0] = OP_MEMORY_IP6;
1196*fcf3ce44SJohn Forte 			lc.data[0].ip = (in6_addr_t *)value;
1197*fcf3ce44SJohn Forte 			NEXT_TLV(op, op_len);
1198*fcf3ce44SJohn Forte 			if (op_len > 8 &&
1199*fcf3ce44SJohn Forte 			    op->attr_id == ISNS_PORTAL_PORT_ATTR_ID) {
1200*fcf3ce44SJohn Forte 				value = &op->attr_value[0];
1201*fcf3ce44SJohn Forte 				lc.id[1] = ATTR_INDEX_PORTAL(
1202*fcf3ce44SJohn Forte 				    ISNS_PORTAL_PORT_ATTR_ID);
1203*fcf3ce44SJohn Forte 				lc.op[1] = OP_INTEGER;
1204*fcf3ce44SJohn Forte 				lc.data[1].ui = ntohl(*(uint32_t *)value);
1205*fcf3ce44SJohn Forte 				lc.op[2] = 0;
1206*fcf3ce44SJohn Forte 				lc.type = OBJ_PORTAL;
1207*fcf3ce44SJohn Forte 			} else {
1208*fcf3ce44SJohn Forte 				ec = ISNS_RSP_MSG_FORMAT_ERROR;
1209*fcf3ce44SJohn Forte 			}
1210*fcf3ce44SJohn Forte 			break;
1211*fcf3ce44SJohn Forte 		case ISNS_PORTAL_INDEX_ATTR_ID:
1212*fcf3ce44SJohn Forte 			lc.id[0] = ATTR_INDEX_PORTAL(
1213*fcf3ce44SJohn Forte 			    ISNS_PORTAL_INDEX_ATTR_ID);
1214*fcf3ce44SJohn Forte 			lc.op[0] = OP_INTEGER;
1215*fcf3ce44SJohn Forte 			lc.data[0].ui = ntohl(*(uint32_t *)value);
1216*fcf3ce44SJohn Forte 			lc.op[1] = 0;
1217*fcf3ce44SJohn Forte 			lc.type = OBJ_PORTAL;
1218*fcf3ce44SJohn Forte 			break;
1219*fcf3ce44SJohn Forte 		default:
1220*fcf3ce44SJohn Forte 			ec = ISNS_RSP_MSG_FORMAT_ERROR;
1221*fcf3ce44SJohn Forte 			break;
1222*fcf3ce44SJohn Forte 		}
1223*fcf3ce44SJohn Forte 		if (ec == 0 &&
1224*fcf3ce44SJohn Forte 		    (ec = dereg_object(&lc, 0)) == 0) {
1225*fcf3ce44SJohn Forte 			if (ctrl == 0 &&
1226*fcf3ce44SJohn Forte #ifndef SKIP_SRC_AUTH
1227*fcf3ce44SJohn Forte 			    lc.curr_uid != 0 &&
1228*fcf3ce44SJohn Forte 			    puid != lc.curr_uid) {
1229*fcf3ce44SJohn Forte #else
1230*fcf3ce44SJohn Forte 			    0) {
1231*fcf3ce44SJohn Forte #endif
1232*fcf3ce44SJohn Forte 				ec = ISNS_RSP_SRC_UNAUTHORIZED;
1233*fcf3ce44SJohn Forte 			} else {
1234*fcf3ce44SJohn Forte 				NEXT_TLV(op, op_len);
1235*fcf3ce44SJohn Forte 			}
1236*fcf3ce44SJohn Forte 		}
1237*fcf3ce44SJohn Forte 	}
1238*fcf3ce44SJohn Forte 
1239*fcf3ce44SJohn Forte 	conn->ec = ec;
1240*fcf3ce44SJohn Forte 
1241*fcf3ce44SJohn Forte 	if (ec != 0) {
1242*fcf3ce44SJohn Forte 		isnslog(LOG_DEBUG, "dev_dereg", "error code: %d", ec);
1243*fcf3ce44SJohn Forte 	}
1244*fcf3ce44SJohn Forte 
1245*fcf3ce44SJohn Forte 	return (0);
1246*fcf3ce44SJohn Forte }
1247*fcf3ce44SJohn Forte 
1248*fcf3ce44SJohn Forte /*
1249*fcf3ce44SJohn Forte  * ****************************************************************************
1250*fcf3ce44SJohn Forte  *
1251*fcf3ce44SJohn Forte  * scn_reg:
1252*fcf3ce44SJohn Forte  *	function which handles the isnsp SCN_REG message.
1253*fcf3ce44SJohn Forte  *
1254*fcf3ce44SJohn Forte  * conn	- the argument of the connection.
1255*fcf3ce44SJohn Forte  * return - 0: the message requires response.
1256*fcf3ce44SJohn Forte  *
1257*fcf3ce44SJohn Forte  * ****************************************************************************
1258*fcf3ce44SJohn Forte  */
1259*fcf3ce44SJohn Forte static int
1260*fcf3ce44SJohn Forte scn_reg(
1261*fcf3ce44SJohn Forte 	conn_arg_t *conn
1262*fcf3ce44SJohn Forte )
1263*fcf3ce44SJohn Forte {
1264*fcf3ce44SJohn Forte 	int ec = 0;
1265*fcf3ce44SJohn Forte 
1266*fcf3ce44SJohn Forte 	/* isns_pdu_t *pdu = conn->in_packet.pdu; */
1267*fcf3ce44SJohn Forte 	/* isns_tlv_t *source = conn->in_packet.source; */
1268*fcf3ce44SJohn Forte 	isns_tlv_t *key = conn->in_packet.key;
1269*fcf3ce44SJohn Forte 	uint16_t key_len = conn->in_packet.key_len;
1270*fcf3ce44SJohn Forte 	isns_tlv_t *op = conn->in_packet.op;
1271*fcf3ce44SJohn Forte 	uint16_t op_len = conn->in_packet.op_len;
1272*fcf3ce44SJohn Forte 
1273*fcf3ce44SJohn Forte 	/* uchar_t *src; */
1274*fcf3ce44SJohn Forte 	uchar_t *node_name;
1275*fcf3ce44SJohn Forte 	uint32_t nlen;
1276*fcf3ce44SJohn Forte 	uint32_t scn;
1277*fcf3ce44SJohn Forte 
1278*fcf3ce44SJohn Forte 	isnslog(LOG_DEBUG, "scn_reg", "entered");
1279*fcf3ce44SJohn Forte 
1280*fcf3ce44SJohn Forte 	/* src = (uchar_t *)&source->attr_value[0]; */
1281*fcf3ce44SJohn Forte 
1282*fcf3ce44SJohn Forte 	if (op == NULL ||
1283*fcf3ce44SJohn Forte 	    op->attr_id != ISNS_ISCSI_SCN_BITMAP_ATTR_ID ||
1284*fcf3ce44SJohn Forte 	    op_len != 12 ||
1285*fcf3ce44SJohn Forte 	    key == NULL ||
1286*fcf3ce44SJohn Forte 	    key->attr_id != ISNS_ISCSI_NAME_ATTR_ID ||
1287*fcf3ce44SJohn Forte 	    key_len != 8 + key->attr_len) {
1288*fcf3ce44SJohn Forte 		ec = ISNS_RSP_MSG_FORMAT_ERROR;
1289*fcf3ce44SJohn Forte 		goto scn_reg_done;
1290*fcf3ce44SJohn Forte 	}
1291*fcf3ce44SJohn Forte 
1292*fcf3ce44SJohn Forte 	node_name = (uchar_t *)&key->attr_value[0];
1293*fcf3ce44SJohn Forte 	nlen = key->attr_len;
1294*fcf3ce44SJohn Forte 	scn = ntohl(*(uint32_t *)&op->attr_value[0]);
1295*fcf3ce44SJohn Forte 
1296*fcf3ce44SJohn Forte 	ec = add_scn_entry(node_name, nlen, scn);
1297*fcf3ce44SJohn Forte 
1298*fcf3ce44SJohn Forte scn_reg_done:
1299*fcf3ce44SJohn Forte 	conn->ec = ec;
1300*fcf3ce44SJohn Forte 
1301*fcf3ce44SJohn Forte 	if (ec != 0) {
1302*fcf3ce44SJohn Forte 		isnslog(LOG_DEBUG, "scn_reg", "error code: %d", ec);
1303*fcf3ce44SJohn Forte 	}
1304*fcf3ce44SJohn Forte 
1305*fcf3ce44SJohn Forte 	return (0);
1306*fcf3ce44SJohn Forte }
1307*fcf3ce44SJohn Forte 
1308*fcf3ce44SJohn Forte /*
1309*fcf3ce44SJohn Forte  * ****************************************************************************
1310*fcf3ce44SJohn Forte  *
1311*fcf3ce44SJohn Forte  * scn_dereg:
1312*fcf3ce44SJohn Forte  *	function which handles the isnsp SCN_DEREG message.
1313*fcf3ce44SJohn Forte  *
1314*fcf3ce44SJohn Forte  * conn	- the argument of the connection.
1315*fcf3ce44SJohn Forte  * return - 0: the message requires response.
1316*fcf3ce44SJohn Forte  *
1317*fcf3ce44SJohn Forte  * ****************************************************************************
1318*fcf3ce44SJohn Forte  */
1319*fcf3ce44SJohn Forte static int
1320*fcf3ce44SJohn Forte scn_dereg(
1321*fcf3ce44SJohn Forte 	conn_arg_t *conn
1322*fcf3ce44SJohn Forte )
1323*fcf3ce44SJohn Forte {
1324*fcf3ce44SJohn Forte 	int ec = 0;
1325*fcf3ce44SJohn Forte 
1326*fcf3ce44SJohn Forte 	isns_tlv_t *key = conn->in_packet.key;
1327*fcf3ce44SJohn Forte 	uint16_t key_len = conn->in_packet.key_len;
1328*fcf3ce44SJohn Forte 
1329*fcf3ce44SJohn Forte 	uchar_t *node_name;
1330*fcf3ce44SJohn Forte 
1331*fcf3ce44SJohn Forte 	isnslog(LOG_DEBUG, "scn_dereg", "entered");
1332*fcf3ce44SJohn Forte 
1333*fcf3ce44SJohn Forte 	if (key != NULL &&
1334*fcf3ce44SJohn Forte 	    key->attr_len != 0 &&
1335*fcf3ce44SJohn Forte 	    key_len == 8 + key->attr_len &&
1336*fcf3ce44SJohn Forte 	    key->attr_id == ISNS_ISCSI_NAME_ATTR_ID) {
1337*fcf3ce44SJohn Forte 		node_name = (uchar_t *)&key->attr_value[0];
1338*fcf3ce44SJohn Forte 		ec = remove_scn_entry(node_name);
1339*fcf3ce44SJohn Forte 	} else {
1340*fcf3ce44SJohn Forte 		ec = ISNS_RSP_MSG_FORMAT_ERROR;
1341*fcf3ce44SJohn Forte 	}
1342*fcf3ce44SJohn Forte 
1343*fcf3ce44SJohn Forte 	conn->ec = ec;
1344*fcf3ce44SJohn Forte 
1345*fcf3ce44SJohn Forte 	if (ec != 0) {
1346*fcf3ce44SJohn Forte 		isnslog(LOG_DEBUG, "scn_dereg", "error code: %d", ec);
1347*fcf3ce44SJohn Forte 	}
1348*fcf3ce44SJohn Forte 
1349*fcf3ce44SJohn Forte 	return (0);
1350*fcf3ce44SJohn Forte }
1351*fcf3ce44SJohn Forte 
1352*fcf3ce44SJohn Forte /*
1353*fcf3ce44SJohn Forte  * ****************************************************************************
1354*fcf3ce44SJohn Forte  *
1355*fcf3ce44SJohn Forte  * setup_ddid_lcp:
1356*fcf3ce44SJohn Forte  *	setup the lookup control data for looking up the DD object
1357*fcf3ce44SJohn Forte  *	by using the dd_id attribute.
1358*fcf3ce44SJohn Forte  *
1359*fcf3ce44SJohn Forte  * lcp	- pointer to the lookup control data.
1360*fcf3ce44SJohn Forte  * dd_id- the unique ID of the DD object.
1361*fcf3ce44SJohn Forte  * return - the pointer to the lcp.
1362*fcf3ce44SJohn Forte  *
1363*fcf3ce44SJohn Forte  * ****************************************************************************
1364*fcf3ce44SJohn Forte  */
1365*fcf3ce44SJohn Forte #ifndef DEBUG
1366*fcf3ce44SJohn Forte static
1367*fcf3ce44SJohn Forte #endif
1368*fcf3ce44SJohn Forte lookup_ctrl_t *
1369*fcf3ce44SJohn Forte setup_ddid_lcp(
1370*fcf3ce44SJohn Forte 	lookup_ctrl_t *lcp,
1371*fcf3ce44SJohn Forte 	uint32_t dd_id
1372*fcf3ce44SJohn Forte )
1373*fcf3ce44SJohn Forte {
1374*fcf3ce44SJohn Forte 	lcp->curr_uid = 0;
1375*fcf3ce44SJohn Forte 	lcp->type = OBJ_DD;
1376*fcf3ce44SJohn Forte 	lcp->id[0] = ATTR_INDEX_DD(ISNS_DD_ID_ATTR_ID);
1377*fcf3ce44SJohn Forte 	lcp->op[0] = OP_INTEGER;
1378*fcf3ce44SJohn Forte 	lcp->data[0].ui = dd_id;
1379*fcf3ce44SJohn Forte 	lcp->op[1] = 0;
1380*fcf3ce44SJohn Forte 
1381*fcf3ce44SJohn Forte 	return (lcp);
1382*fcf3ce44SJohn Forte }
1383*fcf3ce44SJohn Forte 
1384*fcf3ce44SJohn Forte /*
1385*fcf3ce44SJohn Forte  * ****************************************************************************
1386*fcf3ce44SJohn Forte  *
1387*fcf3ce44SJohn Forte  * setup_ddsid_lcp:
1388*fcf3ce44SJohn Forte  *	setup the lookup control data for looking up the DD-set object
1389*fcf3ce44SJohn Forte  *	by using the dds_id attribute.
1390*fcf3ce44SJohn Forte  *
1391*fcf3ce44SJohn Forte  * lcp	- pointer to the lookup control data.
1392*fcf3ce44SJohn Forte  * dds_id - the unique ID of the DD-set object.
1393*fcf3ce44SJohn Forte  * return - the pointer to the lcp.
1394*fcf3ce44SJohn Forte  *
1395*fcf3ce44SJohn Forte  * ****************************************************************************
1396*fcf3ce44SJohn Forte  */
1397*fcf3ce44SJohn Forte #ifndef DEBUG
1398*fcf3ce44SJohn Forte static
1399*fcf3ce44SJohn Forte #endif
1400*fcf3ce44SJohn Forte lookup_ctrl_t *
1401*fcf3ce44SJohn Forte setup_ddsid_lcp(
1402*fcf3ce44SJohn Forte 	lookup_ctrl_t *lcp,
1403*fcf3ce44SJohn Forte 	uint32_t dds_id
1404*fcf3ce44SJohn Forte )
1405*fcf3ce44SJohn Forte {
1406*fcf3ce44SJohn Forte 	lcp->curr_uid = 0;
1407*fcf3ce44SJohn Forte 	lcp->type = OBJ_DDS;
1408*fcf3ce44SJohn Forte 	lcp->id[0] = ATTR_INDEX_DDS(ISNS_DD_SET_ID_ATTR_ID);
1409*fcf3ce44SJohn Forte 	lcp->op[0] = OP_INTEGER;
1410*fcf3ce44SJohn Forte 	lcp->data[0].ui = dds_id;
1411*fcf3ce44SJohn Forte 	lcp->op[1] = 0;
1412*fcf3ce44SJohn Forte 
1413*fcf3ce44SJohn Forte 	return (lcp);
1414*fcf3ce44SJohn Forte }
1415*fcf3ce44SJohn Forte 
1416*fcf3ce44SJohn Forte /*
1417*fcf3ce44SJohn Forte  * ****************************************************************************
1418*fcf3ce44SJohn Forte  *
1419*fcf3ce44SJohn Forte  * dd_reg:
1420*fcf3ce44SJohn Forte  *	function which handles the isnsp DD_REG message.
1421*fcf3ce44SJohn Forte  *
1422*fcf3ce44SJohn Forte  * conn	- the argument of the connection.
1423*fcf3ce44SJohn Forte  * return - 0: the message requires response.
1424*fcf3ce44SJohn Forte  *
1425*fcf3ce44SJohn Forte  * ****************************************************************************
1426*fcf3ce44SJohn Forte  */
1427*fcf3ce44SJohn Forte static int
1428*fcf3ce44SJohn Forte dd_reg(
1429*fcf3ce44SJohn Forte 	conn_arg_t *conn
1430*fcf3ce44SJohn Forte )
1431*fcf3ce44SJohn Forte {
1432*fcf3ce44SJohn Forte 	int ec = 0;
1433*fcf3ce44SJohn Forte 
1434*fcf3ce44SJohn Forte 	/* isns_pdu_t *pdu = conn->in_packet.pdu; */
1435*fcf3ce44SJohn Forte 	isns_tlv_t *source = conn->in_packet.source;
1436*fcf3ce44SJohn Forte 	isns_tlv_t *key = conn->in_packet.key;
1437*fcf3ce44SJohn Forte 	uint16_t key_len = conn->in_packet.key_len;
1438*fcf3ce44SJohn Forte 	isns_tlv_t *op = conn->in_packet.op;
1439*fcf3ce44SJohn Forte 	uint16_t op_len = conn->in_packet.op_len;
1440*fcf3ce44SJohn Forte 
1441*fcf3ce44SJohn Forte 	uint32_t dd_id = 0;
1442*fcf3ce44SJohn Forte 	uint8_t *value;
1443*fcf3ce44SJohn Forte 
1444*fcf3ce44SJohn Forte 	isns_obj_t *dd = NULL;
1445*fcf3ce44SJohn Forte 
1446*fcf3ce44SJohn Forte 	uchar_t *iscsi_name;
1447*fcf3ce44SJohn Forte 
1448*fcf3ce44SJohn Forte 	lookup_ctrl_t lc;
1449*fcf3ce44SJohn Forte 	isns_assoc_iscsi_t aiscsi;
1450*fcf3ce44SJohn Forte 	isns_obj_t *assoc;
1451*fcf3ce44SJohn Forte 	isns_attr_t *attr;
1452*fcf3ce44SJohn Forte 
1453*fcf3ce44SJohn Forte 	uint32_t features;
1454*fcf3ce44SJohn Forte 
1455*fcf3ce44SJohn Forte 	isnslog(LOG_DEBUG, "dd_reg", "entered");
1456*fcf3ce44SJohn Forte 
1457*fcf3ce44SJohn Forte 	iscsi_name = (uchar_t *)&source->attr_value[0];
1458*fcf3ce44SJohn Forte 	if (is_control_node(iscsi_name) == 0) {
1459*fcf3ce44SJohn Forte 		ec = ISNS_RSP_SRC_UNAUTHORIZED;
1460*fcf3ce44SJohn Forte 		goto dd_reg_done;
1461*fcf3ce44SJohn Forte 	}
1462*fcf3ce44SJohn Forte 
1463*fcf3ce44SJohn Forte 	ec = pdu_reset_rsp(&conn->out_packet.pdu,
1464*fcf3ce44SJohn Forte 	    &conn->out_packet.pl,
1465*fcf3ce44SJohn Forte 	    &conn->out_packet.sz);
1466*fcf3ce44SJohn Forte 	if (ec != 0) {
1467*fcf3ce44SJohn Forte 		goto dd_reg_done;
1468*fcf3ce44SJohn Forte 	}
1469*fcf3ce44SJohn Forte 
1470*fcf3ce44SJohn Forte 	if (op == NULL ||
1471*fcf3ce44SJohn Forte 	    (key != NULL &&
1472*fcf3ce44SJohn Forte 	    (key_len != 12 ||
1473*fcf3ce44SJohn Forte 	    key->attr_id != ISNS_DD_ID_ATTR_ID ||
1474*fcf3ce44SJohn Forte 	    key->attr_len != 4 ||
1475*fcf3ce44SJohn Forte 	    (dd_id = ntohl(*(uint32_t *)&key->attr_value[0])) == 0 ||
1476*fcf3ce44SJohn Forte 	    is_obj_there(setup_ddid_lcp(&lc, dd_id)) == 0))) {
1477*fcf3ce44SJohn Forte 		ec = ISNS_RSP_INVALID_REGIS;
1478*fcf3ce44SJohn Forte 		goto dd_reg_done;
1479*fcf3ce44SJohn Forte 	}
1480*fcf3ce44SJohn Forte 
1481*fcf3ce44SJohn Forte 	/* message key */
1482*fcf3ce44SJohn Forte 	if (key != NULL &&
1483*fcf3ce44SJohn Forte 	    (ec = rsp_add_tlv(conn, ISNS_DD_ID_ATTR_ID, 4,
1484*fcf3ce44SJohn Forte 	    (void *)dd_id, 0)) != 0) {
1485*fcf3ce44SJohn Forte 		goto dd_reg_done;
1486*fcf3ce44SJohn Forte 	}
1487*fcf3ce44SJohn Forte 
1488*fcf3ce44SJohn Forte 	/* delimiter */
1489*fcf3ce44SJohn Forte 	if ((ec = rsp_add_tlv(conn, ISNS_DELIMITER_ATTR_ID, 0,
1490*fcf3ce44SJohn Forte 	    NULL, 0)) != 0) {
1491*fcf3ce44SJohn Forte 		goto dd_reg_done;
1492*fcf3ce44SJohn Forte 	}
1493*fcf3ce44SJohn Forte 
1494*fcf3ce44SJohn Forte 	/* A DDReg message with no Message Key SHALL result in the */
1495*fcf3ce44SJohn Forte 	/* attempted creation of a new Discovery Domain (DD). */
1496*fcf3ce44SJohn Forte 	if (dd_id == 0) {
1497*fcf3ce44SJohn Forte 		ec = create_dd_object(op, op_len, &dd);
1498*fcf3ce44SJohn Forte 		if (ec == 0) {
1499*fcf3ce44SJohn Forte 			ec = register_object(dd, &dd_id, NULL);
1500*fcf3ce44SJohn Forte 			if (ec == ERR_NAME_IN_USE) {
1501*fcf3ce44SJohn Forte 				ec = ISNS_RSP_INVALID_REGIS;
1502*fcf3ce44SJohn Forte 			}
1503*fcf3ce44SJohn Forte 			if (ec != 0) {
1504*fcf3ce44SJohn Forte 				free_object(dd);
1505*fcf3ce44SJohn Forte 				goto dd_reg_done;
1506*fcf3ce44SJohn Forte 			}
1507*fcf3ce44SJohn Forte 		} else {
1508*fcf3ce44SJohn Forte 			goto dd_reg_done;
1509*fcf3ce44SJohn Forte 		}
1510*fcf3ce44SJohn Forte 	}
1511*fcf3ce44SJohn Forte 
1512*fcf3ce44SJohn Forte 	/* add the newly created dd to the response */
1513*fcf3ce44SJohn Forte 	if (dd != NULL) {
1514*fcf3ce44SJohn Forte 		ec = rsp_add_op(conn, dd);
1515*fcf3ce44SJohn Forte 	}
1516*fcf3ce44SJohn Forte 
1517*fcf3ce44SJohn Forte 	aiscsi.type = OBJ_ASSOC_ISCSI;
1518*fcf3ce44SJohn Forte 	aiscsi.puid = dd_id;
1519*fcf3ce44SJohn Forte 
1520*fcf3ce44SJohn Forte 	while (op_len > 8 && ec == 0) {
1521*fcf3ce44SJohn Forte 		value = &op->attr_value[0];
1522*fcf3ce44SJohn Forte 		switch (op->attr_id) {
1523*fcf3ce44SJohn Forte 		case ISNS_DD_ID_ATTR_ID:
1524*fcf3ce44SJohn Forte 			/* if the DD_ID is included in both the Message Key */
1525*fcf3ce44SJohn Forte 			/* and Operating Attributes, then the DD_ID value */
1526*fcf3ce44SJohn Forte 			/* in the Message Key MUST be the same as the DD_ID */
1527*fcf3ce44SJohn Forte 			/* value in the Operating Attributes. */
1528*fcf3ce44SJohn Forte 			if (dd == NULL) {
1529*fcf3ce44SJohn Forte 				if (op->attr_len != 4 ||
1530*fcf3ce44SJohn Forte 				    dd_id != ntohl(*(uint32_t *)value)) {
1531*fcf3ce44SJohn Forte 					ec = ISNS_RSP_INVALID_REGIS;
1532*fcf3ce44SJohn Forte 				} else {
1533*fcf3ce44SJohn Forte 					ec = rsp_add_tlv(conn,
1534*fcf3ce44SJohn Forte 					    ISNS_DD_ID_ATTR_ID, 4,
1535*fcf3ce44SJohn Forte 					    (void *)dd_id, 0);
1536*fcf3ce44SJohn Forte 				}
1537*fcf3ce44SJohn Forte 			}
1538*fcf3ce44SJohn Forte 			break;
1539*fcf3ce44SJohn Forte 		case ISNS_DD_NAME_ATTR_ID:
1540*fcf3ce44SJohn Forte 			/* It is going to modify the DD Symbolic Name. */
1541*fcf3ce44SJohn Forte 			if (dd == NULL) {
1542*fcf3ce44SJohn Forte 				if (op->attr_len > 0 && op->attr_len <= 256) {
1543*fcf3ce44SJohn Forte 					ec = update_dd_name(
1544*fcf3ce44SJohn Forte 					    dd_id,
1545*fcf3ce44SJohn Forte 					    op->attr_len,
1546*fcf3ce44SJohn Forte 					    (uchar_t *)value);
1547*fcf3ce44SJohn Forte 					if (ec == ERR_NAME_IN_USE) {
1548*fcf3ce44SJohn Forte 						ec = ISNS_RSP_INVALID_REGIS;
1549*fcf3ce44SJohn Forte 					}
1550*fcf3ce44SJohn Forte 				} else {
1551*fcf3ce44SJohn Forte 					ec = ISNS_RSP_INVALID_REGIS;
1552*fcf3ce44SJohn Forte 				}
1553*fcf3ce44SJohn Forte 				if (ec == 0) {
1554*fcf3ce44SJohn Forte 					ec = rsp_add_tlv(conn,
1555*fcf3ce44SJohn Forte 					    ISNS_DD_NAME_ATTR_ID,
1556*fcf3ce44SJohn Forte 					    op->attr_len, (void *)value, 1);
1557*fcf3ce44SJohn Forte 				}
1558*fcf3ce44SJohn Forte 			}
1559*fcf3ce44SJohn Forte 			break;
1560*fcf3ce44SJohn Forte 		case ISNS_DD_ISCSI_INDEX_ATTR_ID:
1561*fcf3ce44SJohn Forte 			if (op->attr_len == 4) {
1562*fcf3ce44SJohn Forte 				/* zero the association object */
1563*fcf3ce44SJohn Forte 				attr = &aiscsi.attrs[ATTR_INDEX_ASSOC_ISCSI(
1564*fcf3ce44SJohn Forte 				    ISNS_DD_ISCSI_INDEX_ATTR_ID)];
1565*fcf3ce44SJohn Forte 				attr->tag = ISNS_DD_ISCSI_INDEX_ATTR_ID;
1566*fcf3ce44SJohn Forte 				attr->len = 4;
1567*fcf3ce44SJohn Forte 				attr->value.ui = ntohl(*(uint32_t *)value);
1568*fcf3ce44SJohn Forte 				attr = &aiscsi.attrs[ATTR_INDEX_ASSOC_ISCSI(
1569*fcf3ce44SJohn Forte 				    ISNS_DD_ISCSI_NAME_ATTR_ID)];
1570*fcf3ce44SJohn Forte 				attr->tag = 0; /* clear it */
1571*fcf3ce44SJohn Forte 				attr->value.ptr = NULL; /* clear it */
1572*fcf3ce44SJohn Forte 				assoc = (isns_obj_t *)&aiscsi;
1573*fcf3ce44SJohn Forte 				if ((ec = add_dd_member(assoc)) ==
1574*fcf3ce44SJohn Forte 				    ERR_ALREADY_ASSOCIATED) {
1575*fcf3ce44SJohn Forte 					ec = 0;
1576*fcf3ce44SJohn Forte 				}
1577*fcf3ce44SJohn Forte 				if (attr->value.ptr != NULL) {
1578*fcf3ce44SJohn Forte 					free(attr->value.ptr);
1579*fcf3ce44SJohn Forte 				}
1580*fcf3ce44SJohn Forte 			} else {
1581*fcf3ce44SJohn Forte 				ec = ISNS_RSP_INVALID_REGIS;
1582*fcf3ce44SJohn Forte 			}
1583*fcf3ce44SJohn Forte 			if (ec == 0) {
1584*fcf3ce44SJohn Forte 				ec = rsp_add_tlv(conn,
1585*fcf3ce44SJohn Forte 				    ISNS_DD_ISCSI_INDEX_ATTR_ID,
1586*fcf3ce44SJohn Forte 				    4, (void *)attr->value.ui, 0);
1587*fcf3ce44SJohn Forte 			}
1588*fcf3ce44SJohn Forte 			break;
1589*fcf3ce44SJohn Forte 		case ISNS_DD_ISCSI_NAME_ATTR_ID:
1590*fcf3ce44SJohn Forte 			if (op->attr_len > 0 && op->attr_len <= 224) {
1591*fcf3ce44SJohn Forte 				attr = &aiscsi.attrs[ATTR_INDEX_ASSOC_ISCSI(
1592*fcf3ce44SJohn Forte 				    ISNS_DD_ISCSI_NAME_ATTR_ID)];
1593*fcf3ce44SJohn Forte 				attr->tag = ISNS_DD_ISCSI_NAME_ATTR_ID;
1594*fcf3ce44SJohn Forte 				attr->len = op->attr_len;
1595*fcf3ce44SJohn Forte 				attr->value.ptr = (uchar_t *)value;
1596*fcf3ce44SJohn Forte 				attr = &aiscsi.attrs[ATTR_INDEX_ASSOC_ISCSI(
1597*fcf3ce44SJohn Forte 				    ISNS_DD_ISCSI_INDEX_ATTR_ID)];
1598*fcf3ce44SJohn Forte 				attr->tag = 0; /* clear it */
1599*fcf3ce44SJohn Forte 				assoc = (isns_obj_t *)&aiscsi;
1600*fcf3ce44SJohn Forte 				if ((ec = add_dd_member(assoc)) ==
1601*fcf3ce44SJohn Forte 				    ERR_ALREADY_ASSOCIATED) {
1602*fcf3ce44SJohn Forte 					ec = 0;
1603*fcf3ce44SJohn Forte 				}
1604*fcf3ce44SJohn Forte 			} else {
1605*fcf3ce44SJohn Forte 				ec = ISNS_RSP_INVALID_REGIS;
1606*fcf3ce44SJohn Forte 			}
1607*fcf3ce44SJohn Forte 			if (ec == 0) {
1608*fcf3ce44SJohn Forte 				ec = rsp_add_tlv(conn,
1609*fcf3ce44SJohn Forte 				    ISNS_DD_ISCSI_NAME_ATTR_ID,
1610*fcf3ce44SJohn Forte 				    op->attr_len, (void *)value, 1);
1611*fcf3ce44SJohn Forte 			}
1612*fcf3ce44SJohn Forte 			break;
1613*fcf3ce44SJohn Forte 		case ISNS_DD_FC_PORT_NAME_ATTR_ID:
1614*fcf3ce44SJohn Forte 		case ISNS_DD_PORTAL_INDEX_ATTR_ID:
1615*fcf3ce44SJohn Forte 		case ISNS_DD_PORTAL_IP_ADDR_ATTR_ID:
1616*fcf3ce44SJohn Forte 		case ISNS_DD_PORTAL_PORT_ATTR_ID:
1617*fcf3ce44SJohn Forte 			ec = ISNS_RSP_REGIS_NOT_SUPPORTED;
1618*fcf3ce44SJohn Forte 			break;
1619*fcf3ce44SJohn Forte 		case ISNS_DD_FEATURES_ATTR_ID:
1620*fcf3ce44SJohn Forte 			/* It is going to modify the DD Symbolic Name. */
1621*fcf3ce44SJohn Forte 			if (dd == NULL) {
1622*fcf3ce44SJohn Forte 				if (op->attr_len == 4) {
1623*fcf3ce44SJohn Forte 					features = ntohl(*(uint32_t *)value);
1624*fcf3ce44SJohn Forte 					ec = update_dd_features(
1625*fcf3ce44SJohn Forte 					    dd_id, features);
1626*fcf3ce44SJohn Forte 				} else {
1627*fcf3ce44SJohn Forte 					ec = ISNS_RSP_INVALID_REGIS;
1628*fcf3ce44SJohn Forte 				}
1629*fcf3ce44SJohn Forte 				if (ec == 0) {
1630*fcf3ce44SJohn Forte 					ec = rsp_add_tlv(conn,
1631*fcf3ce44SJohn Forte 					    ISNS_DD_FEATURES_ATTR_ID,
1632*fcf3ce44SJohn Forte 					    4, (void *)features, 0);
1633*fcf3ce44SJohn Forte 				}
1634*fcf3ce44SJohn Forte 			}
1635*fcf3ce44SJohn Forte 			break;
1636*fcf3ce44SJohn Forte 		default:
1637*fcf3ce44SJohn Forte 			ec = ISNS_RSP_INVALID_REGIS;
1638*fcf3ce44SJohn Forte 			break;
1639*fcf3ce44SJohn Forte 		}
1640*fcf3ce44SJohn Forte 
1641*fcf3ce44SJohn Forte 		NEXT_TLV(op, op_len);
1642*fcf3ce44SJohn Forte 	}
1643*fcf3ce44SJohn Forte 
1644*fcf3ce44SJohn Forte dd_reg_done:
1645*fcf3ce44SJohn Forte 	conn->ec = ec;
1646*fcf3ce44SJohn Forte 
1647*fcf3ce44SJohn Forte 	if (ec != 0) {
1648*fcf3ce44SJohn Forte 		isnslog(LOG_DEBUG, "dd_reg", "error code: %d", ec);
1649*fcf3ce44SJohn Forte 	}
1650*fcf3ce44SJohn Forte 
1651*fcf3ce44SJohn Forte 	return (0);
1652*fcf3ce44SJohn Forte }
1653*fcf3ce44SJohn Forte 
1654*fcf3ce44SJohn Forte /*
1655*fcf3ce44SJohn Forte  * ****************************************************************************
1656*fcf3ce44SJohn Forte  *
1657*fcf3ce44SJohn Forte  * dds_reg:
1658*fcf3ce44SJohn Forte  *	function which handles the isnsp DDS_REG message.
1659*fcf3ce44SJohn Forte  *
1660*fcf3ce44SJohn Forte  * conn	- the argument of the connection.
1661*fcf3ce44SJohn Forte  * return - 0: the message requires response.
1662*fcf3ce44SJohn Forte  *
1663*fcf3ce44SJohn Forte  * ****************************************************************************
1664*fcf3ce44SJohn Forte  */
1665*fcf3ce44SJohn Forte static int
1666*fcf3ce44SJohn Forte dds_reg(
1667*fcf3ce44SJohn Forte 	conn_arg_t *conn
1668*fcf3ce44SJohn Forte )
1669*fcf3ce44SJohn Forte {
1670*fcf3ce44SJohn Forte 	int ec = 0;
1671*fcf3ce44SJohn Forte 
1672*fcf3ce44SJohn Forte 	/* isns_pdu_t *pdu = conn->in_packet.pdu; */
1673*fcf3ce44SJohn Forte 	isns_tlv_t *source = conn->in_packet.source;
1674*fcf3ce44SJohn Forte 	isns_tlv_t *key = conn->in_packet.key;
1675*fcf3ce44SJohn Forte 	uint16_t key_len = conn->in_packet.key_len;
1676*fcf3ce44SJohn Forte 	isns_tlv_t *op = conn->in_packet.op;
1677*fcf3ce44SJohn Forte 	uint16_t op_len = conn->in_packet.op_len;
1678*fcf3ce44SJohn Forte 
1679*fcf3ce44SJohn Forte 	uint32_t dds_id = 0;
1680*fcf3ce44SJohn Forte 	uint8_t *value;
1681*fcf3ce44SJohn Forte 
1682*fcf3ce44SJohn Forte 	isns_obj_t *dds = NULL;
1683*fcf3ce44SJohn Forte 
1684*fcf3ce44SJohn Forte 	uchar_t *iscsi_name;
1685*fcf3ce44SJohn Forte 
1686*fcf3ce44SJohn Forte 	lookup_ctrl_t lc;
1687*fcf3ce44SJohn Forte 	isns_assoc_dd_t add;
1688*fcf3ce44SJohn Forte 	isns_obj_t *assoc;
1689*fcf3ce44SJohn Forte 	isns_attr_t *attr;
1690*fcf3ce44SJohn Forte 
1691*fcf3ce44SJohn Forte 	uint32_t code;
1692*fcf3ce44SJohn Forte 
1693*fcf3ce44SJohn Forte 	isnslog(LOG_DEBUG, "dds_reg", "entered");
1694*fcf3ce44SJohn Forte 
1695*fcf3ce44SJohn Forte 	iscsi_name = (uchar_t *)&source->attr_value[0];
1696*fcf3ce44SJohn Forte 	if (is_control_node(iscsi_name) == 0) {
1697*fcf3ce44SJohn Forte 		ec = ISNS_RSP_SRC_UNAUTHORIZED;
1698*fcf3ce44SJohn Forte 		goto dds_reg_done;
1699*fcf3ce44SJohn Forte 	}
1700*fcf3ce44SJohn Forte 
1701*fcf3ce44SJohn Forte 	ec = pdu_reset_rsp(&conn->out_packet.pdu,
1702*fcf3ce44SJohn Forte 	    &conn->out_packet.pl,
1703*fcf3ce44SJohn Forte 	    &conn->out_packet.sz);
1704*fcf3ce44SJohn Forte 	if (ec != 0) {
1705*fcf3ce44SJohn Forte 		goto dds_reg_done;
1706*fcf3ce44SJohn Forte 	}
1707*fcf3ce44SJohn Forte 
1708*fcf3ce44SJohn Forte 	if (op == NULL ||
1709*fcf3ce44SJohn Forte 	    (key != NULL &&
1710*fcf3ce44SJohn Forte 	    (key_len != 12 ||
1711*fcf3ce44SJohn Forte 	    key->attr_id != ISNS_DD_SET_ID_ATTR_ID ||
1712*fcf3ce44SJohn Forte 	    key->attr_len != 4 ||
1713*fcf3ce44SJohn Forte 	    (dds_id = ntohl(*(uint32_t *)&key->attr_value[0])) == 0 ||
1714*fcf3ce44SJohn Forte 	    is_obj_there(setup_ddsid_lcp(&lc, dds_id)) == 0))) {
1715*fcf3ce44SJohn Forte 		ec = ISNS_RSP_INVALID_REGIS;
1716*fcf3ce44SJohn Forte 		goto dds_reg_done;
1717*fcf3ce44SJohn Forte 	}
1718*fcf3ce44SJohn Forte 
1719*fcf3ce44SJohn Forte 	/* message key */
1720*fcf3ce44SJohn Forte 	if (key != NULL &&
1721*fcf3ce44SJohn Forte 	    (ec = rsp_add_tlv(conn, ISNS_DD_SET_ID_ATTR_ID, 4,
1722*fcf3ce44SJohn Forte 	    (void *)dds_id, 0)) != 0) {
1723*fcf3ce44SJohn Forte 		goto dds_reg_done;
1724*fcf3ce44SJohn Forte 	}
1725*fcf3ce44SJohn Forte 
1726*fcf3ce44SJohn Forte 	/* delimiter */
1727*fcf3ce44SJohn Forte 	if ((ec = rsp_add_tlv(conn, ISNS_DELIMITER_ATTR_ID, 0,
1728*fcf3ce44SJohn Forte 	    NULL, 0)) != 0) {
1729*fcf3ce44SJohn Forte 		goto dds_reg_done;
1730*fcf3ce44SJohn Forte 	}
1731*fcf3ce44SJohn Forte 
1732*fcf3ce44SJohn Forte 	/* A DDSReg message with no Message Key SHALL result in the */
1733*fcf3ce44SJohn Forte 	/* attempted creation of a new Discovery Domain (DD). */
1734*fcf3ce44SJohn Forte 	if (dds_id == 0) {
1735*fcf3ce44SJohn Forte 		ec = create_dds_object(op, op_len, &dds);
1736*fcf3ce44SJohn Forte 		if (ec == 0) {
1737*fcf3ce44SJohn Forte 			ec = register_object(dds, &dds_id, NULL);
1738*fcf3ce44SJohn Forte 			if (ec == ERR_NAME_IN_USE) {
1739*fcf3ce44SJohn Forte 				ec = ISNS_RSP_INVALID_REGIS;
1740*fcf3ce44SJohn Forte 			}
1741*fcf3ce44SJohn Forte 			if (ec != 0) {
1742*fcf3ce44SJohn Forte 				free_object(dds);
1743*fcf3ce44SJohn Forte 				goto dds_reg_done;
1744*fcf3ce44SJohn Forte 			}
1745*fcf3ce44SJohn Forte 		} else {
1746*fcf3ce44SJohn Forte 			goto dds_reg_done;
1747*fcf3ce44SJohn Forte 		}
1748*fcf3ce44SJohn Forte 	}
1749*fcf3ce44SJohn Forte 
1750*fcf3ce44SJohn Forte 	/* add the newly created dd to the response */
1751*fcf3ce44SJohn Forte 	if (dds != NULL) {
1752*fcf3ce44SJohn Forte 		ec = rsp_add_op(conn, dds);
1753*fcf3ce44SJohn Forte 	}
1754*fcf3ce44SJohn Forte 
1755*fcf3ce44SJohn Forte 	add.type = OBJ_ASSOC_DD;
1756*fcf3ce44SJohn Forte 	add.puid = dds_id;
1757*fcf3ce44SJohn Forte 
1758*fcf3ce44SJohn Forte 	while (op_len > 8 && ec == 0) {
1759*fcf3ce44SJohn Forte 		value = &op->attr_value[0];
1760*fcf3ce44SJohn Forte 		switch (op->attr_id) {
1761*fcf3ce44SJohn Forte 		case ISNS_DD_SET_ID_ATTR_ID:
1762*fcf3ce44SJohn Forte 			/* if the DDS_ID is included in both the Message Key */
1763*fcf3ce44SJohn Forte 			/* and Operating Attributes, then the DDS_ID value */
1764*fcf3ce44SJohn Forte 			/* in the Message Key MUST be the same as the DDS_ID */
1765*fcf3ce44SJohn Forte 			/* value in the Operating Attributes. */
1766*fcf3ce44SJohn Forte 			if (dds == NULL) {
1767*fcf3ce44SJohn Forte 				if (op->attr_len != 4 ||
1768*fcf3ce44SJohn Forte 				    dds_id != ntohl(*(uint32_t *)value)) {
1769*fcf3ce44SJohn Forte 					ec = ISNS_RSP_INVALID_REGIS;
1770*fcf3ce44SJohn Forte 				} else {
1771*fcf3ce44SJohn Forte 					ec = rsp_add_tlv(conn,
1772*fcf3ce44SJohn Forte 					    ISNS_DD_SET_ID_ATTR_ID,
1773*fcf3ce44SJohn Forte 					    4, (void *)dds_id, 0);
1774*fcf3ce44SJohn Forte 				}
1775*fcf3ce44SJohn Forte 			}
1776*fcf3ce44SJohn Forte 			break;
1777*fcf3ce44SJohn Forte 		case ISNS_DD_SET_NAME_ATTR_ID:
1778*fcf3ce44SJohn Forte 			/* It is going to modify the DD Symbolic Name. */
1779*fcf3ce44SJohn Forte 			if (dds == NULL) {
1780*fcf3ce44SJohn Forte 				if (op->attr_len > 0 && op->attr_len <= 256) {
1781*fcf3ce44SJohn Forte 					ec = update_dds_name(
1782*fcf3ce44SJohn Forte 					    dds_id,
1783*fcf3ce44SJohn Forte 					    op->attr_len,
1784*fcf3ce44SJohn Forte 					    (uchar_t *)value);
1785*fcf3ce44SJohn Forte 					if (ec == ERR_NAME_IN_USE) {
1786*fcf3ce44SJohn Forte 						ec = ISNS_RSP_INVALID_REGIS;
1787*fcf3ce44SJohn Forte 					}
1788*fcf3ce44SJohn Forte 				} else {
1789*fcf3ce44SJohn Forte 					ec = ISNS_RSP_INVALID_REGIS;
1790*fcf3ce44SJohn Forte 				}
1791*fcf3ce44SJohn Forte 				if (ec == 0) {
1792*fcf3ce44SJohn Forte 					ec = rsp_add_tlv(conn,
1793*fcf3ce44SJohn Forte 					    ISNS_DD_SET_NAME_ATTR_ID,
1794*fcf3ce44SJohn Forte 					    op->attr_len, (void *)value, 1);
1795*fcf3ce44SJohn Forte 				}
1796*fcf3ce44SJohn Forte 			}
1797*fcf3ce44SJohn Forte 			break;
1798*fcf3ce44SJohn Forte 		case ISNS_DD_SET_STATUS_ATTR_ID:
1799*fcf3ce44SJohn Forte 			/* It is going to modify the DD Symbolic Name. */
1800*fcf3ce44SJohn Forte 			if (dds == NULL) {
1801*fcf3ce44SJohn Forte 				if (op->attr_len == 4) {
1802*fcf3ce44SJohn Forte 					code = ntohl(*(uint32_t *)value);
1803*fcf3ce44SJohn Forte 					ec = update_dds_status(
1804*fcf3ce44SJohn Forte 					    dds_id, code);
1805*fcf3ce44SJohn Forte 				} else {
1806*fcf3ce44SJohn Forte 					ec = ISNS_RSP_INVALID_REGIS;
1807*fcf3ce44SJohn Forte 				}
1808*fcf3ce44SJohn Forte 				if (ec == 0) {
1809*fcf3ce44SJohn Forte 					ec = rsp_add_tlv(conn,
1810*fcf3ce44SJohn Forte 					    ISNS_DD_SET_STATUS_ATTR_ID,
1811*fcf3ce44SJohn Forte 					    4, (void *)code, 0);
1812*fcf3ce44SJohn Forte 				}
1813*fcf3ce44SJohn Forte 			}
1814*fcf3ce44SJohn Forte 			break;
1815*fcf3ce44SJohn Forte 		case ISNS_DD_ID_ATTR_ID:
1816*fcf3ce44SJohn Forte 			if (op->attr_len == 4) {
1817*fcf3ce44SJohn Forte 				/* zero the association object */
1818*fcf3ce44SJohn Forte 				attr = &add.attrs[ATTR_INDEX_ASSOC_DD(
1819*fcf3ce44SJohn Forte 				    ISNS_DD_ID_ATTR_ID)];
1820*fcf3ce44SJohn Forte 				attr->tag = ISNS_DD_ID_ATTR_ID;
1821*fcf3ce44SJohn Forte 				attr->len = 4;
1822*fcf3ce44SJohn Forte 				attr->value.ui = ntohl(*(uint32_t *)value);
1823*fcf3ce44SJohn Forte 				assoc = (isns_obj_t *)&add;
1824*fcf3ce44SJohn Forte 				if ((ec = add_dds_member(assoc)) ==
1825*fcf3ce44SJohn Forte 				    ERR_ALREADY_ASSOCIATED) {
1826*fcf3ce44SJohn Forte 					ec = 0;
1827*fcf3ce44SJohn Forte 				}
1828*fcf3ce44SJohn Forte 			} else {
1829*fcf3ce44SJohn Forte 				ec = ISNS_RSP_INVALID_REGIS;
1830*fcf3ce44SJohn Forte 			}
1831*fcf3ce44SJohn Forte 			if (ec == 0) {
1832*fcf3ce44SJohn Forte 				ec = rsp_add_tlv(conn,
1833*fcf3ce44SJohn Forte 				    ISNS_DD_ID_ATTR_ID, 4,
1834*fcf3ce44SJohn Forte 				    (void *)attr->value.ui, 0);
1835*fcf3ce44SJohn Forte 			}
1836*fcf3ce44SJohn Forte 			break;
1837*fcf3ce44SJohn Forte 		default:
1838*fcf3ce44SJohn Forte 			ec = ISNS_RSP_INVALID_REGIS;
1839*fcf3ce44SJohn Forte 			break;
1840*fcf3ce44SJohn Forte 		}
1841*fcf3ce44SJohn Forte 
1842*fcf3ce44SJohn Forte 		NEXT_TLV(op, op_len);
1843*fcf3ce44SJohn Forte 	}
1844*fcf3ce44SJohn Forte 
1845*fcf3ce44SJohn Forte dds_reg_done:
1846*fcf3ce44SJohn Forte 	conn->ec = ec;
1847*fcf3ce44SJohn Forte 
1848*fcf3ce44SJohn Forte 	if (ec != 0) {
1849*fcf3ce44SJohn Forte 		isnslog(LOG_DEBUG, "dds_reg", "error code: %d", ec);
1850*fcf3ce44SJohn Forte 	}
1851*fcf3ce44SJohn Forte 
1852*fcf3ce44SJohn Forte 	return (0);
1853*fcf3ce44SJohn Forte }
1854*fcf3ce44SJohn Forte 
1855*fcf3ce44SJohn Forte /*
1856*fcf3ce44SJohn Forte  * ****************************************************************************
1857*fcf3ce44SJohn Forte  *
1858*fcf3ce44SJohn Forte  * dd_dereg:
1859*fcf3ce44SJohn Forte  *	function which handles the isnsp DD_DEREG message.
1860*fcf3ce44SJohn Forte  *
1861*fcf3ce44SJohn Forte  * conn	- the argument of the connection.
1862*fcf3ce44SJohn Forte  * return - 0: the message requires response.
1863*fcf3ce44SJohn Forte  *
1864*fcf3ce44SJohn Forte  * ****************************************************************************
1865*fcf3ce44SJohn Forte  */
1866*fcf3ce44SJohn Forte static int
1867*fcf3ce44SJohn Forte dd_dereg(
1868*fcf3ce44SJohn Forte 	conn_arg_t *conn
1869*fcf3ce44SJohn Forte )
1870*fcf3ce44SJohn Forte {
1871*fcf3ce44SJohn Forte 	int ec = 0;
1872*fcf3ce44SJohn Forte 
1873*fcf3ce44SJohn Forte 	/* isns_pdu_t *pdu = conn->in_packet.pdu; */
1874*fcf3ce44SJohn Forte 	isns_tlv_t *source = conn->in_packet.source;
1875*fcf3ce44SJohn Forte 	isns_tlv_t *key = conn->in_packet.key;
1876*fcf3ce44SJohn Forte 	uint16_t key_len = conn->in_packet.key_len;
1877*fcf3ce44SJohn Forte 	isns_tlv_t *op = conn->in_packet.op;
1878*fcf3ce44SJohn Forte 	uint16_t op_len = conn->in_packet.op_len;
1879*fcf3ce44SJohn Forte 
1880*fcf3ce44SJohn Forte 	uint32_t dd_id;
1881*fcf3ce44SJohn Forte 	uint8_t *value;
1882*fcf3ce44SJohn Forte 
1883*fcf3ce44SJohn Forte 	uchar_t *iscsi_name;
1884*fcf3ce44SJohn Forte 
1885*fcf3ce44SJohn Forte 	isns_assoc_iscsi_t aiscsi;
1886*fcf3ce44SJohn Forte 	isns_obj_t *assoc;
1887*fcf3ce44SJohn Forte 	isns_attr_t *attr;
1888*fcf3ce44SJohn Forte 
1889*fcf3ce44SJohn Forte 	isnslog(LOG_DEBUG, "dd_dereg", "entered");
1890*fcf3ce44SJohn Forte 
1891*fcf3ce44SJohn Forte 	iscsi_name = (uchar_t *)&source->attr_value[0];
1892*fcf3ce44SJohn Forte 	if (is_control_node(iscsi_name) == 0) {
1893*fcf3ce44SJohn Forte 		ec = ISNS_RSP_SRC_UNAUTHORIZED;
1894*fcf3ce44SJohn Forte 		goto dd_dereg_done;
1895*fcf3ce44SJohn Forte 	}
1896*fcf3ce44SJohn Forte 
1897*fcf3ce44SJohn Forte 	if (key == NULL ||
1898*fcf3ce44SJohn Forte 	    key_len != 12 ||
1899*fcf3ce44SJohn Forte 	    key->attr_id != ISNS_DD_ID_ATTR_ID ||
1900*fcf3ce44SJohn Forte 	    (dd_id = ntohl(*(uint32_t *)&key->attr_value[0])) == 0) {
1901*fcf3ce44SJohn Forte 		ec = ISNS_RSP_MSG_FORMAT_ERROR;
1902*fcf3ce44SJohn Forte 		goto dd_dereg_done;
1903*fcf3ce44SJohn Forte 	}
1904*fcf3ce44SJohn Forte 
1905*fcf3ce44SJohn Forte 	if (op == NULL) {
1906*fcf3ce44SJohn Forte 		ec = remove_dd_object(dd_id);
1907*fcf3ce44SJohn Forte 	} else {
1908*fcf3ce44SJohn Forte 		aiscsi.type = OBJ_ASSOC_ISCSI;
1909*fcf3ce44SJohn Forte 		aiscsi.puid = dd_id;
1910*fcf3ce44SJohn Forte 
1911*fcf3ce44SJohn Forte 		while (op_len > 8 && ec == 0) {
1912*fcf3ce44SJohn Forte 			value = &op->attr_value[0];
1913*fcf3ce44SJohn Forte 			switch (op->attr_id) {
1914*fcf3ce44SJohn Forte 			case ISNS_DD_ISCSI_INDEX_ATTR_ID:
1915*fcf3ce44SJohn Forte 				/* zero the association object */
1916*fcf3ce44SJohn Forte 				attr = &aiscsi.attrs[ATTR_INDEX_ASSOC_ISCSI(
1917*fcf3ce44SJohn Forte 				    ISNS_DD_ISCSI_INDEX_ATTR_ID)];
1918*fcf3ce44SJohn Forte 				attr->tag = ISNS_DD_ISCSI_INDEX_ATTR_ID;
1919*fcf3ce44SJohn Forte 				attr->len = 4;
1920*fcf3ce44SJohn Forte 				attr->value.ui = ntohl(*(uint32_t *)value);
1921*fcf3ce44SJohn Forte 				attr = &aiscsi.attrs[ATTR_INDEX_ASSOC_ISCSI(
1922*fcf3ce44SJohn Forte 				    ISNS_DD_ISCSI_NAME_ATTR_ID)];
1923*fcf3ce44SJohn Forte 				attr->tag = 0; /* clear it */
1924*fcf3ce44SJohn Forte 				attr->value.ptr = NULL; /* clear it */
1925*fcf3ce44SJohn Forte 				assoc = (isns_obj_t *)&aiscsi;
1926*fcf3ce44SJohn Forte 				if ((ec = remove_dd_member(assoc)) ==
1927*fcf3ce44SJohn Forte 				    ERR_NO_SUCH_ASSOCIATION) {
1928*fcf3ce44SJohn Forte 					ec = 0;
1929*fcf3ce44SJohn Forte 				}
1930*fcf3ce44SJohn Forte 				if (attr->value.ptr != NULL) {
1931*fcf3ce44SJohn Forte 					free(attr->value.ptr);
1932*fcf3ce44SJohn Forte 				}
1933*fcf3ce44SJohn Forte 				break;
1934*fcf3ce44SJohn Forte 			case ISNS_DD_ISCSI_NAME_ATTR_ID:
1935*fcf3ce44SJohn Forte 				attr = &aiscsi.attrs[ATTR_INDEX_ASSOC_ISCSI(
1936*fcf3ce44SJohn Forte 				    ISNS_DD_ISCSI_NAME_ATTR_ID)];
1937*fcf3ce44SJohn Forte 				attr->tag = ISNS_DD_ISCSI_NAME_ATTR_ID;
1938*fcf3ce44SJohn Forte 				attr->len = op->attr_len;
1939*fcf3ce44SJohn Forte 				attr->value.ptr = (uchar_t *)value;
1940*fcf3ce44SJohn Forte 				attr = &aiscsi.attrs[ATTR_INDEX_ASSOC_ISCSI(
1941*fcf3ce44SJohn Forte 				    ISNS_DD_ISCSI_INDEX_ATTR_ID)];
1942*fcf3ce44SJohn Forte 				attr->tag = 0; /* clear it */
1943*fcf3ce44SJohn Forte 				assoc = (isns_obj_t *)&aiscsi;
1944*fcf3ce44SJohn Forte 				if ((ec = remove_dd_member(assoc)) ==
1945*fcf3ce44SJohn Forte 				    ERR_NO_SUCH_ASSOCIATION) {
1946*fcf3ce44SJohn Forte 					ec = 0;
1947*fcf3ce44SJohn Forte 				}
1948*fcf3ce44SJohn Forte 				break;
1949*fcf3ce44SJohn Forte 			case ISNS_DD_FC_PORT_NAME_ATTR_ID:
1950*fcf3ce44SJohn Forte 			case ISNS_DD_PORTAL_INDEX_ATTR_ID:
1951*fcf3ce44SJohn Forte 			case ISNS_DD_PORTAL_IP_ADDR_ATTR_ID:
1952*fcf3ce44SJohn Forte 			case ISNS_DD_PORTAL_PORT_ATTR_ID:
1953*fcf3ce44SJohn Forte 				ec = ISNS_RSP_REGIS_NOT_SUPPORTED;
1954*fcf3ce44SJohn Forte 				break;
1955*fcf3ce44SJohn Forte 			default:
1956*fcf3ce44SJohn Forte 				ec = ISNS_RSP_MSG_FORMAT_ERROR;
1957*fcf3ce44SJohn Forte 				break;
1958*fcf3ce44SJohn Forte 			}
1959*fcf3ce44SJohn Forte 
1960*fcf3ce44SJohn Forte 			NEXT_TLV(op, op_len);
1961*fcf3ce44SJohn Forte 		}
1962*fcf3ce44SJohn Forte 	}
1963*fcf3ce44SJohn Forte 
1964*fcf3ce44SJohn Forte dd_dereg_done:
1965*fcf3ce44SJohn Forte 	conn->ec = ec;
1966*fcf3ce44SJohn Forte 
1967*fcf3ce44SJohn Forte 	if (ec != 0) {
1968*fcf3ce44SJohn Forte 		isnslog(LOG_DEBUG, "dd_dereg", "error code: %d", ec);
1969*fcf3ce44SJohn Forte 	}
1970*fcf3ce44SJohn Forte 
1971*fcf3ce44SJohn Forte 	return (0);
1972*fcf3ce44SJohn Forte }
1973*fcf3ce44SJohn Forte 
1974*fcf3ce44SJohn Forte /*
1975*fcf3ce44SJohn Forte  * ****************************************************************************
1976*fcf3ce44SJohn Forte  *
1977*fcf3ce44SJohn Forte  * dds_dereg:
1978*fcf3ce44SJohn Forte  *	function which handles the isnsp DDS_DEREG message.
1979*fcf3ce44SJohn Forte  *
1980*fcf3ce44SJohn Forte  * conn	- the argument of the connection.
1981*fcf3ce44SJohn Forte  * return - 0: the message requires response.
1982*fcf3ce44SJohn Forte  *
1983*fcf3ce44SJohn Forte  * ****************************************************************************
1984*fcf3ce44SJohn Forte  */
1985*fcf3ce44SJohn Forte static int
1986*fcf3ce44SJohn Forte dds_dereg(
1987*fcf3ce44SJohn Forte 	conn_arg_t *conn
1988*fcf3ce44SJohn Forte )
1989*fcf3ce44SJohn Forte {
1990*fcf3ce44SJohn Forte 	int ec = 0;
1991*fcf3ce44SJohn Forte 
1992*fcf3ce44SJohn Forte 	/* isns_pdu_t *pdu = conn->in_packet.pdu; */
1993*fcf3ce44SJohn Forte 	isns_tlv_t *source = conn->in_packet.source;
1994*fcf3ce44SJohn Forte 	isns_tlv_t *key = conn->in_packet.key;
1995*fcf3ce44SJohn Forte 	uint16_t key_len = conn->in_packet.key_len;
1996*fcf3ce44SJohn Forte 	isns_tlv_t *op = conn->in_packet.op;
1997*fcf3ce44SJohn Forte 	uint16_t op_len = conn->in_packet.op_len;
1998*fcf3ce44SJohn Forte 
1999*fcf3ce44SJohn Forte 	uint32_t dds_id;
2000*fcf3ce44SJohn Forte 	uint32_t uid;
2001*fcf3ce44SJohn Forte 	uint8_t *value;
2002*fcf3ce44SJohn Forte 
2003*fcf3ce44SJohn Forte 	uchar_t *iscsi_name;
2004*fcf3ce44SJohn Forte 
2005*fcf3ce44SJohn Forte 	isnslog(LOG_DEBUG, "dds_dereg", "entered");
2006*fcf3ce44SJohn Forte 
2007*fcf3ce44SJohn Forte 	iscsi_name = (uchar_t *)&source->attr_value[0];
2008*fcf3ce44SJohn Forte 	if (is_control_node(iscsi_name) == 0) {
2009*fcf3ce44SJohn Forte 		ec = ISNS_RSP_SRC_UNAUTHORIZED;
2010*fcf3ce44SJohn Forte 		goto dds_dereg_done;
2011*fcf3ce44SJohn Forte 	}
2012*fcf3ce44SJohn Forte 
2013*fcf3ce44SJohn Forte 	if (key == NULL ||
2014*fcf3ce44SJohn Forte 	    key_len != 12 ||
2015*fcf3ce44SJohn Forte 	    key->attr_id != ISNS_DD_SET_ID_ATTR_ID ||
2016*fcf3ce44SJohn Forte 	    (dds_id = ntohl(*(uint32_t *)&key->attr_value[0])) == 0) {
2017*fcf3ce44SJohn Forte 		ec = ISNS_RSP_MSG_FORMAT_ERROR;
2018*fcf3ce44SJohn Forte 		goto dds_dereg_done;
2019*fcf3ce44SJohn Forte 	}
2020*fcf3ce44SJohn Forte 
2021*fcf3ce44SJohn Forte 	if (op == NULL) {
2022*fcf3ce44SJohn Forte 		ec = remove_dds_object(dds_id);
2023*fcf3ce44SJohn Forte 	} else {
2024*fcf3ce44SJohn Forte 		while (op_len > 8 && ec == 0) {
2025*fcf3ce44SJohn Forte 			value = &op->attr_value[0];
2026*fcf3ce44SJohn Forte 			if (op->attr_id == ISNS_DD_ID_ATTR_ID) {
2027*fcf3ce44SJohn Forte 				uid = ntohl(*(uint32_t *)value);
2028*fcf3ce44SJohn Forte 				if ((ec = remove_dds_member(dds_id, uid)) ==
2029*fcf3ce44SJohn Forte 				    ERR_NO_SUCH_ASSOCIATION) {
2030*fcf3ce44SJohn Forte 					ec = 0;
2031*fcf3ce44SJohn Forte 				}
2032*fcf3ce44SJohn Forte 			} else {
2033*fcf3ce44SJohn Forte 				ec = ISNS_RSP_MSG_FORMAT_ERROR;
2034*fcf3ce44SJohn Forte 			}
2035*fcf3ce44SJohn Forte 
2036*fcf3ce44SJohn Forte 			NEXT_TLV(op, op_len);
2037*fcf3ce44SJohn Forte 		}
2038*fcf3ce44SJohn Forte 	}
2039*fcf3ce44SJohn Forte 
2040*fcf3ce44SJohn Forte dds_dereg_done:
2041*fcf3ce44SJohn Forte 	conn->ec = ec;
2042*fcf3ce44SJohn Forte 
2043*fcf3ce44SJohn Forte 	if (ec != 0) {
2044*fcf3ce44SJohn Forte 		isnslog(LOG_DEBUG, "dds_dereg", "error code: %d", ec);
2045*fcf3ce44SJohn Forte 	}
2046*fcf3ce44SJohn Forte 
2047*fcf3ce44SJohn Forte 	return (0);
2048*fcf3ce44SJohn Forte }
2049*fcf3ce44SJohn Forte 
2050*fcf3ce44SJohn Forte /*
2051*fcf3ce44SJohn Forte  * ****************************************************************************
2052*fcf3ce44SJohn Forte  *
2053*fcf3ce44SJohn Forte  * msg_error:
2054*fcf3ce44SJohn Forte  *	function which handles any unknown isnsp messages or the
2055*fcf3ce44SJohn Forte  *	messages which are not supported.
2056*fcf3ce44SJohn Forte  *
2057*fcf3ce44SJohn Forte  * conn	- the argument of the connection.
2058*fcf3ce44SJohn Forte  * return - 0: the message requires response.
2059*fcf3ce44SJohn Forte  *
2060*fcf3ce44SJohn Forte  * ****************************************************************************
2061*fcf3ce44SJohn Forte  */
2062*fcf3ce44SJohn Forte static int
2063*fcf3ce44SJohn Forte msg_error(
2064*fcf3ce44SJohn Forte 	/* LINTED E_FUNC_ARG_UNUSED */
2065*fcf3ce44SJohn Forte 	conn_arg_t *conn
2066*fcf3ce44SJohn Forte )
2067*fcf3ce44SJohn Forte {
2068*fcf3ce44SJohn Forte 	return (0);
2069*fcf3ce44SJohn Forte }
2070*fcf3ce44SJohn Forte 
2071*fcf3ce44SJohn Forte /*
2072*fcf3ce44SJohn Forte  * ****************************************************************************
2073*fcf3ce44SJohn Forte  *
2074*fcf3ce44SJohn Forte  * isns_response_ec:
2075*fcf3ce44SJohn Forte  *	send the response message to the client with error code.
2076*fcf3ce44SJohn Forte  *
2077*fcf3ce44SJohn Forte  * so	- the socket descriptor.
2078*fcf3ce44SJohn Forte  * pdu	- the received pdu.
2079*fcf3ce44SJohn Forte  * ec	- the error code which is being responsed.
2080*fcf3ce44SJohn Forte  * return - status of the sending operation.
2081*fcf3ce44SJohn Forte  *
2082*fcf3ce44SJohn Forte  * ****************************************************************************
2083*fcf3ce44SJohn Forte  */
2084*fcf3ce44SJohn Forte static int
2085*fcf3ce44SJohn Forte isns_response_ec(
2086*fcf3ce44SJohn Forte 	int so,
2087*fcf3ce44SJohn Forte 	isns_pdu_t *pdu,
2088*fcf3ce44SJohn Forte 	int ec
2089*fcf3ce44SJohn Forte )
2090*fcf3ce44SJohn Forte {
2091*fcf3ce44SJohn Forte 	int status;
2092*fcf3ce44SJohn Forte 
2093*fcf3ce44SJohn Forte 	uint8_t buff[sizeof (isns_pdu_t) + 8];
2094*fcf3ce44SJohn Forte 
2095*fcf3ce44SJohn Forte 	isns_pdu_t *rsp = (isns_pdu_t *)&buff;
2096*fcf3ce44SJohn Forte 	isns_resp_t *resp = (isns_resp_t *)rsp->payload;
2097*fcf3ce44SJohn Forte 	size_t pl = 4;
2098*fcf3ce44SJohn Forte 
2099*fcf3ce44SJohn Forte 	rsp->version = htons((uint16_t)ISNSP_VERSION);
2100*fcf3ce44SJohn Forte 	rsp->func_id = htons(pdu->func_id | ISNS_RSP_MASK);
2101*fcf3ce44SJohn Forte 	rsp->xid = htons(pdu->xid);
2102*fcf3ce44SJohn Forte 	resp->status = htonl(ec);
2103*fcf3ce44SJohn Forte 
2104*fcf3ce44SJohn Forte 	status = isns_send_pdu(so, rsp, pl);
2105*fcf3ce44SJohn Forte 
2106*fcf3ce44SJohn Forte 	return (status);
2107*fcf3ce44SJohn Forte }
2108*fcf3ce44SJohn Forte 
2109*fcf3ce44SJohn Forte /*
2110*fcf3ce44SJohn Forte  * ****************************************************************************
2111*fcf3ce44SJohn Forte  *
2112*fcf3ce44SJohn Forte  * isns_response:
2113*fcf3ce44SJohn Forte  *	send the response message to the client.
2114*fcf3ce44SJohn Forte  *
2115*fcf3ce44SJohn Forte  * conn	- the argument of the connection.
2116*fcf3ce44SJohn Forte  * return - status of the sending operation.
2117*fcf3ce44SJohn Forte  *
2118*fcf3ce44SJohn Forte  * ****************************************************************************
2119*fcf3ce44SJohn Forte  */
2120*fcf3ce44SJohn Forte int
2121*fcf3ce44SJohn Forte isns_response(
2122*fcf3ce44SJohn Forte 	conn_arg_t *conn
2123*fcf3ce44SJohn Forte )
2124*fcf3ce44SJohn Forte {
2125*fcf3ce44SJohn Forte 	int status;
2126*fcf3ce44SJohn Forte 
2127*fcf3ce44SJohn Forte 	int so = conn->so;
2128*fcf3ce44SJohn Forte 	int ec = conn->ec;
2129*fcf3ce44SJohn Forte 	isns_pdu_t *pdu = conn->in_packet.pdu;
2130*fcf3ce44SJohn Forte 	isns_pdu_t *rsp = conn->out_packet.pdu;
2131*fcf3ce44SJohn Forte 	size_t pl = conn->out_packet.pl;
2132*fcf3ce44SJohn Forte 
2133*fcf3ce44SJohn Forte 	if (rsp != NULL) {
2134*fcf3ce44SJohn Forte 		rsp->version = htons((uint16_t)ISNSP_VERSION);
2135*fcf3ce44SJohn Forte 		rsp->func_id = htons(pdu->func_id | ISNS_RSP_MASK);
2136*fcf3ce44SJohn Forte 		rsp->xid = htons(pdu->xid);
2137*fcf3ce44SJohn Forte 		(void) pdu_update_code(rsp, &pl, ec);
2138*fcf3ce44SJohn Forte 		status = isns_send_pdu(so, rsp, pl);
2139*fcf3ce44SJohn Forte 	} else {
2140*fcf3ce44SJohn Forte 		status = isns_response_ec(so, pdu, ec);
2141*fcf3ce44SJohn Forte 	}
2142*fcf3ce44SJohn Forte 
2143*fcf3ce44SJohn Forte 	return (status);
2144*fcf3ce44SJohn Forte }
2145