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