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