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