Emulex Logo
OneCoreā„¢ Storage SDK Release 11.2
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ocs_isns.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011-2015, Emulex
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice,
12  * this list of conditions and the following disclaimer in the documentation
13  * and/or other materials provided with the distribution.
14  *
15  * 3. Neither the name of the copyright holder nor the names of its contributors
16  * may be used to endorse or promote products derived from this software
17  * without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  *
31  */
32 
33 /**
34  * @file
35  * Implements the iSNS functions.
36  */
37 
38 /**
39  * @defgroup isns iSCSI iSNS utilities
40  */
41 
42 #include "ocs.h"
43 #include "ocs_isns.h"
44 #include "ocs_iscsi.h"
45 #include "ocs_iscsi_api.h"
46 
47 /**
48  * @ingroup isns
49  * @brief Initialize the iSNS module
50  *
51  * This function will initialize any iSNS required structures
52  *
53  * @param iscsi pointer to the iSCSI structure that represents this device
54  *
55  * @return 0 if success
56  */
57 int32_t
59 {
60  return 0;
61 }
62 
63 /**
64  * @ingroup isns
65  * @brief Shutdown the iSNS module
66  *
67  * This function will free any iSNS resources prior to driver shutdown
68  *
69  * @param iscsi pointer to the iSCSI structure that represents this device
70  *
71  * @return 0 if success
72  */
73 int32_t
75 {
76  return 0;
77 }
78 
79 /**
80  * @ingroup isns
81  * @brief Determines whether a given isns attribute is a numeric (binary) one
82  *
83  * @param tag The tag of the isns attribute in query
84  *
85  * @return 0 if success
86  */
87 static int
89 {
90  switch (tag){
91  case ISNS_TAG_ENTITY_PROTOCOL : return 1;
92  case ISNS_TAG_REG_PERIOD : return 1;
93  case ISNS_TAG_PORTAL_TCP_PORT : return 1;
94  case ISNS_TAG_ESI_INTERVAL : return 1;
95  case ISNS_TAG_ESI_PORT : return 1;
96  case ISNS_TAG_PORTAL_INDEX : return 1;
97  case ISNS_TAG_ISCSI_NODE_TYPE: return 1;
98  default: return 0;
99  }
100 }
101 
102 /**
103  * @ingroup isns
104  * @brief Prints a number of empty lines
105  *
106  * @param iscsi Pointer to the iSCSI structure that represents this device
107  * @param ctr the number of empty lines to be printed
108  */
109 static void
110 ocs_print_nl(ocs_iscsi_t *iscsi, uint32_t ctr)
111 {
112  while(ctr>0) {
113  ocs_isns_log(iscsi->os, "\n");
114  ctr--;
115  }
116 }
117 
118 /**
119  * @ingroup isns
120  * @brief Gets the name of the given isns tag
121  *
122  * @param tag The number of the tag
123  * @return returns the tag name
124  */
125 static char*
126 ocs_get_tag_name(uint32_t tag)
127 {
128  switch (tag) {
129  case ISNS_TAG_DELIMITER : return "delimiter";
130  case ISNS_TAG_ENTITY_IDENTIFIER : return "Entity ID";
131  case ISNS_TAG_ENTITY_PROTOCOL : return "Entity Protocol";
132  case ISNS_TAG_REG_PERIOD : return "Registration Period";
133  case ISNS_TAG_PORTAL_IP_ADDRESS : return "Portal IP Address";
134  case ISNS_TAG_PORTAL_TCP_PORT : return "Portal TCP/UDP Port";
135  case ISNS_TAG_ESI_INTERVAL : return "ESI Interval";
136  case ISNS_TAG_ESI_PORT : return "ESI Port";
137  case ISNS_TAG_PORTAL_INDEX : return "Portal Index";
138  case ISNS_TAG_ISCSI_NAME : return "iSCSI Name";
139  case ISNS_TAG_ISCSI_NODE_TYPE : return "iSCSI Node Type";
140  case ISNS_TAG_ISCSI_ALIAS : return "iSCSI Alias";
141  default : return "Undefined Tag Name";
142  }
143 }
144 
145 /**
146  * @ingroup isns
147  * @brief Gets the name of the given isns error
148  *
149  * @param error_number The number of the error
150  * @return returns the error name
151  */
152 static char*
153 ocs_get_error_name(uint32_t error_number)
154 {
155  switch (error_number) {
156  case ISNS_ERROR_UNKNOWN : return "Unknown Error" ;
157  case ISNS_ERROR_MSG_FORMAT : return "Message Format Error";
158  case ISNS_ERROR_INVALID_REG : return "Invalid Registration";
159  case ISNS_ERROR_RESERVED : return "RESERVED";
160  case ISNS_ERROR_INVALID_QUERY : return "Invalid Query";
161  case ISNS_ERROR_SOURCE_UNKNOWN : return "Source Unknown";
162  case ISNS_ERROR_SOURCE_ABSENT : return "Source Absent";
163  case ISNS_ERROR_SOURCE_UNATHORIZED : return "Source Unauthorized";
164  case ISNS_ERROR_NO_SUCH_ENTRY : return "No Such Entry";
165  case ISNS_ERROR_VERSION_NOT_SUPPORTED : return "Version Not Supported";
166  case ISNS_ERROR_INTERNAL_ERROR : return "Internal Error";
167  case ISNS_ERROR_BUSY : return "Busy";
168  case ISNS_ERROR_OPTION_NOT_UNDERSTOOD : return "Option Not Understood";
169  case ISNS_ERROR_INVALID_UPDATE : return "Invalid Update";
170  case ISNS_ERROR_FUNC_ID : return "Message (FUNCTION_ID) Not Supported";
171  case ISNS_ERROR_SCN_EVENT_REJ : return "SCN Event Rejected";
172  case ISNS_ERROR_SCN_REG_REJ : return "SCN Registration Rejected";
173  case ISNS_ERROR_NOT_IMPL : return "Attribute Not Implemented";
174  case ISNS_ERROR_DOMAIN_ID_UNAVAILABLE : return "FC_DOMAIN_ID Not Available";
175  case ISNS_ERROR_UNALLCATED_DOMAIN_ID : return "FC_DOMAIN_ID Not Allocated";
176  case ISNS_ERROR_ESI_UNAVAILABLE : return "ESI Not Available";
177  case ISNS_ERROR_INVALID_DEREG : return "Invalid Deregistration";
178  case ISNS_ERROR_REG_FEATURE_UNSUPPORTED : return "Registration Feature Not Supported";
179  default : return "UNDEFINED ERROR CODE!";
180  }
181 }
182 
183 /**
184  * @ingroup isns
185  * @brief Creates an empty isns node
186  *
187  * This function will create an empty isns node and allocates memory for
188  * the given number of ip_port structs
189  *
190  * @param iscsi Pointer to the iSCSI structure that represents this device
191  * @param ptr Pointer that determines where to create this node
192  * @param num The number of ip-port structs in that node
193  * @return returns 0 if successful, negative otherwise.
194  */
195 static int8_t
196 ocs_create_node(ocs_iscsi_t *iscsi, void *ptr, uint16_t num)
197 {
198  ocs_isns_node_t n;
199 
200  ocs_memset(&n, 0, sizeof(ocs_isns_node_t));
201  n.ipp_count = num;
202  n.ipp = ocs_malloc(iscsi->os, n.ipp_count * sizeof(ocs_isns_ip_port_t), OCS_M_ZERO | OCS_M_NOWAIT);
203  if (!n.ipp) {
204  ocs_log_test(iscsi->os, "iSNS ERROR: Failed to create the node\n");
205  return -1;
206  }
207 
208  ocs_memcpy(ptr, &n, sizeof(ocs_isns_node_t));
209  ocs_isns_log(iscsi->os, "A node created with ipp_count=%d\n", n.ipp_count);
210  return 0;
211 }
212 
213 /**
214  * @ingroup isns
215  * @brief Gets the iscsi name of a given node
216  *
217  * @param iscsi Pointer to the iSCSI structure that represents this device
218  * @param p Pointer to the start of the nodes table
219  * @param index determines the index of the node in query
220  * @return returns the iscsi name of that node
221  */
222 char *
223 ocs_get_iscsi_name(ocs_iscsi_t *iscsi, void *p, uint16_t index)
224 {
225  ocs_isns_node_t *n = (ocs_isns_node_t *) (p + index * sizeof(ocs_isns_node_t));
226  //ocs_isns_log(iscsi->os, "node #%d has iname = %s\n", index, n->iname);
227  return n->iname;
228 }
229 
230 /**
231  * @ingroup isns
232  * @brief Gets the count of the ip_port structs in a given node
233  *
234  * @param iscsi Pointer to the iSCSI structure that represents this device
235  * @param p Pointer to the start of the nodes table
236  * @param index determines the index of the node in query
237  * @return returns the number of the ip_port structs in this node
238  */
239 uint16_t
240 ocs_get_iscsi_ipp_count(ocs_iscsi_t *iscsi, void *p, uint16_t index)
241 {
242  ocs_isns_node_t *n = (ocs_isns_node_t *) (p + index * sizeof(ocs_isns_node_t));
243  ocs_isns_log(iscsi->os, "node #%d has ipp_count = %d\n", index, n->ipp_count);
244  return n->ipp_count;
245 }
246 
247 /**
248  * @ingroup isns
249  * @brief Converts a string ip into an ip struct
250  *
251  * @param iscsi Pointer to the iSCSI structure that represents this device
252  * @param *ip Pointer to the ip string
253  * @param *ip_struct Pointer to the ip_struct to contain the given string ip
254  */
255 void
256 ocs_str_to_ip_struct(ocs_iscsi_t *iscsi, char *ip, ocs_ip_address_t *ip_struct)
257 {
258  char v4_start[16] = "0:0:0:0:0:ffff";
259  char temp[15];
260  uint8_t i;
261 
262  if(ip == NULL){
263  ocs_log_test(iscsi->os, "iSNS ERROR: ip pointer is NULL");
264  return;
265  }
266  temp[14] = '\0';
267  ocs_memcpy(temp, ip, 14);
268  if(ocs_strcmp(temp, v4_start)) { //v6
269  if(ocs_iscsi_inet_pton6(ip, ip_struct)) {
270  ocs_isns_log(iscsi->os, "invalid v6 ip address\n");
271  return;
272  }
273  } else { //v4
274  if(ocs_iscsi_inet_pton6(ip, ip_struct)) {
275  ocs_isns_log(iscsi->os, "invalid v4 ip address\n");
276  return;
277  } else {
278  ip_struct->ip_type = OCS_IP_TYPE_V4;
279  for( i = 0; i < 4; i++) {
280  ip_struct->ip_address[i] = ip_struct->ip_address[12 + i];
281  }
282  for( i = 4; i < 16; i++) {
283  ip_struct->ip_address[i] = 0;
284  }
285  }
286  }
287  return;
288 }
289 
290 /**
291  * @ingroup isns
292  * @brief Gets the ip address of a given isns node
293  *
294  * @param iscsi Pointer to the iSCSI structure that represents this device
295  * @param p Pointer to the start of the nodes table
296  * @param index determines the index of the node in query
297  * @param ip_index determines which ip-port structure to be selected
298  * @return returns the ip string of this node
299  */
300 char *
301 ocs_get_ip(ocs_iscsi_t *iscsi, void *p, uint16_t index, uint16_t ip_index)
302 {
303  ocs_isns_node_t *n = (ocs_isns_node_t *) (p + index * sizeof(ocs_isns_node_t));
304  ocs_isns_ip_port_t *ipp = NULL;
305 
306  if(ip_index > n->ipp_count - 1) {
307  ocs_isns_log(iscsi->os, "This node has only %d ips\n", n->ipp_count);
308  return NULL;
309  }
310  ipp = n->ipp + ip_index;
311  return ipp->ip;
312 }
313 
314 /**
315  * @ingroup isns
316  * @brief Gets the port of a given isns node
317  *
318  * @param iscsi Pointer to the iSCSI structure that represents this device
319  * @param p Pointer to the start of the nodes table
320  * @param index determines the index of the node in query
321  * @param ip_index determines which ip-port structure to be selected
322  * @return returns the port of this node
323  */
324 uint16_t
325 ocs_get_port(ocs_iscsi_t *iscsi, void *p, uint16_t index, uint16_t ip_index)
326 {
327  ocs_isns_node_t *n = (ocs_isns_node_t *) (p + index * sizeof(ocs_isns_node_t));
328  ocs_isns_ip_port_t *ipp = NULL;
329 
330  if(ip_index > n->ipp_count - 1) {
331  ocs_isns_log(iscsi->os, "This node has only %d ips\n", n->ipp_count);
332  return 0;
333  }
334  ipp = n->ipp + ip_index;
335  return ipp->port;
336 }
337 
338 /**
339  * @ingroup isns
340  * @brief Creates an isns node
341  *
342  * This function will create an isns node by parsing the response message
343  *
344  * @param iscsi Pointer to the iSCSI structure that represents this device
345  * @param rsp_ptr Pointer to the start of the nodes in the operating attributes
346  * @param bytes_left Number of bytes left in the response message
347  * @param ret Pointer to the node to be created
348  * @return returns 0 if successful, negative otherwise.
349  */
350 static int8_t
351 ocs_create_nodes(ocs_iscsi_t *iscsi, void *rsp_ptr, int16_t bytes_left, void *ret)
352 {
353  uint8_t passed_first_node = 0;
354  uint16_t ipps_count = 0;
355  uint16_t nodes_index = 0;
356  uint32_t tag, len;
357 
358  ocs_print_nl(iscsi, 2);
359  ocs_isns_log(iscsi->os, "\t\t\tCreate an isns node begin\n");
360 
361  while (bytes_left > 0) {
362  ocs_memcpy(&tag, rsp_ptr, 4);
363  tag = ocs_be32toh(tag);
364  bytes_left -= 4;
365  rsp_ptr += 4;
366 
367  ocs_memcpy(&len, rsp_ptr, 4);
368  len = ocs_be32toh(len);
369  bytes_left -= 4;
370  rsp_ptr += 4;
371 
372  if(tag == ISNS_TAG_ISCSI_NAME && !(passed_first_node)) {
373  passed_first_node = 1;
374  } else if (tag == ISNS_TAG_ISCSI_NAME && passed_first_node) {
375  ipps_count /= 2;
376  ocs_isns_log(iscsi->os, "node #%d has %d ipps\n", nodes_index++, ipps_count);
377  if( ocs_create_node(iscsi, ret, ipps_count) != 0){
378  ocs_log_err(iscsi->os, "iSNS ERROR: can't create a node!\n");
379  return -1;
380  }
381  ret += sizeof(ocs_isns_node_t);
382  ipps_count = 0;
383  } else if (tag == ISNS_TAG_PORTAL_IP_ADDRESS || tag == ISNS_TAG_PORTAL_TCP_PORT) {
384  ipps_count++;
385  } else if (tag == ISNS_TAG_PORTAL_TCP_PORT) {
386  /* skip */
387  } else {
388  ocs_log_test(iscsi->os, "ERROR: UNDEFINED ATTR 0x%x between the NODES!!\n", tag);
389  return -1;
390  }
391  bytes_left -= len;
392  rsp_ptr += len;
393 
394  if(bytes_left == 0) {//create last node with this num_ipps
395  ipps_count /= 2;
396  ocs_isns_log(iscsi->os, "node #%d has %d ipps\n", nodes_index++, ipps_count);
397  if( ocs_create_node(iscsi, ret, ipps_count) != 0){
398  ocs_log_err(iscsi->os, "iSNS ERROR: can't create a node!\n");
399  return -1;
400  }
401  ret += sizeof(ocs_isns_node_t);
402  }
403  }
404  return 0;
405 }
406 
407 /**
408  * @ingroup isns
409  * @brief Fills the attributes of the isns node
410  *
411  * This function will fills the ip and port attributes of the given node
412  * by parsing the response message
413  *
414  * @param iscsi Pointer to the iSCSI structure that represents this device
415  * @param rsp_ptr Pointer to the start of the nodes in the operating attributes
416  * @param bytes_left Number of bytes left in the response message
417  * @param ret Pointer to the node to be filled
418  */
419 static void
420 ocs_fill_nodes_values(ocs_iscsi_t * iscsi, void *rsp_ptr, int16_t bytes_left, void *ret)
421 {
422  uint32_t tag, len;
423  uint32_t v32;
424  char ip_addr[48];
425  ocs_ip_type_e ip_type = OCS_IP_TYPE_V6;
426  ocs_isns_node_t *temp_node = NULL;
427  ocs_isns_ip_port_t *temp_ipp = NULL;
428  uint16_t nodes_index = 0;
429  uint16_t ipp_index = 0;
430 
431  ocs_print_nl(iscsi, 2);
432  ocs_isns_log(iscsi->os, "\t\t\tISNS node fill attributes\n");
433 
434  while (bytes_left > 0) {
435  ocs_memcpy(&tag, rsp_ptr, 4);
436  tag = ocs_be32toh(tag);
437  bytes_left -= 4;
438  rsp_ptr += 4;
439 
440  ocs_memcpy(&len, rsp_ptr, 4);
441  len = ocs_be32toh(len);
442  bytes_left -= 4;
443  rsp_ptr += 4;
444 
445  if(tag == ISNS_TAG_ISCSI_NAME) {
446  temp_node = (ocs_isns_node_t *) (ret + nodes_index * sizeof(ocs_isns_node_t));
447 
448  ocs_memcpy(temp_node->iname, rsp_ptr, len );
449  nodes_index++;
450  ipp_index = 0;
451  } else if (tag == ISNS_TAG_PORTAL_IP_ADDRESS) {
452  format_ip_address(ip_type , rsp_ptr, ip_addr, ARRAY_SIZE(ip_addr) );
453  temp_ipp = (ocs_isns_ip_port_t *) (temp_node->ipp + ipp_index);
454  ocs_memcpy(temp_ipp->ip, ip_addr, ocs_strlen(ip_addr));
455 
456  } else if (tag == ISNS_TAG_PORTAL_TCP_PORT) {
457  temp_ipp = (ocs_isns_ip_port_t *) (temp_node->ipp + ipp_index);
458  v32 = ocs_htobe32( * (uint32_t *) rsp_ptr);
459  ocs_memcpy(&temp_ipp->port, &v32, sizeof(uint32_t));
460 
461  ipp_index++;
462  } else {
463  ocs_log_test(iscsi->os, "ERROR: UNDEFINED ATTR 0x%x between the NODES!!\n", tag);
464  return;
465  }
466  bytes_left -= len;
467  rsp_ptr += len;
468  }
469 
470  ocs_isns_log(iscsi->os, "\t\t\tISNS node fill attributes done\n");
471  return;
472 }
473 
474 /**
475  * @ingroup isns
476  * @brief Builds the header of the DevAttrReg message
477  *
478  * @param curr Pointer to the start of the attribute
479  * @param len the length of the PDU of that message
480  * @return returns the number of bytes allocated for this attribute
481  */
482 static int
483 ocs_build_hdr_dev_attr_reg(void *curr, uint16_t len)
484 {
485  isns_hdr_t hdr;
486  hdr.iSNSP_version= ocs_htobe16(ISNS_VERSION);
487  hdr.function_id= ocs_htobe16(ISNS_FUNC_DEV_ATTR_REG);
488  hdr.payload_length= ocs_htobe16(len);
490  hdr.transaction_id = ocs_htobe16(ISNS_TRANSACTION_ID_1);
491  hdr.sequence_id = ocs_htobe16(ISNS_STARTING_SEQ_ID);
492  ocs_memcpy(curr, &hdr, sizeof(isns_hdr_t));
493  return sizeof(isns_hdr_t);
494 }
495 
496 
497 /**
498  * @ingroup isns
499  * @brief Builds the header of the DevAttrDereg message
500  *
501  * @param curr Pointer to the start of the attribute
502  * @param len the length of the PDU of that message
503  * @return returns the number of bytes allocated for this attribute
504  */
505 static int
506 ocs_build_hdr_dev_dereg(void *curr, uint16_t len)
507 {
508  isns_hdr_t hdr;
509  hdr.iSNSP_version= ocs_htobe16(ISNS_VERSION);
510  hdr.function_id= ocs_htobe16(ISNS_FUNC_DEV_ATTR_DEREG);
511  hdr.payload_length= ocs_htobe16(len);
513  hdr.transaction_id = ocs_htobe16(ISNS_TRANSACTION_ID_1);
514  hdr.sequence_id = ocs_htobe16(ISNS_STARTING_SEQ_ID);
515  ocs_memcpy(curr, &hdr, sizeof(isns_hdr_t));
516  return sizeof(isns_hdr_t);
517 }
518 
519 /**
520  * @ingroup isns
521  * @brief Builds the header of the DevAttrQry message
522  *
523  * @param curr Pointer to the start of the attribute
524  * @param len the length of the PDU of that message
525  * @return returns the number of bytes allocated for this attribute
526  */
527 static int
528 ocs_build_hdr_dev_attr_qry(void *curr, uint16_t len)
529 {
530  isns_hdr_t hdr;
531  hdr.iSNSP_version= ocs_htobe16(ISNS_VERSION);
532  hdr.function_id= ocs_htobe16(ISNS_FUNC_DEV_ATTR_QRY);
533  hdr.payload_length= ocs_htobe16(len);
535  hdr.transaction_id = ocs_htobe16(ISNS_TRANSACTION_ID_2);
536  hdr.sequence_id = ocs_htobe16(ISNS_STARTING_SEQ_ID);
537  ocs_memcpy(curr, &hdr, sizeof(isns_hdr_t));
538  return sizeof(isns_hdr_t);
539 }
540 
541 /**
542  * @ingroup isns
543  * @brief Create a delimiter attribute
544  *
545  * This function will form a delimiter attribute (0-length and 0-tag attribute)
546  * for the isns messages
547  *
548  * @param curr Pointer to the start of the attribute
549  * @param remaining the number of bytes left in the memory allocated for this msg
550  * @return returns the number of bytes allocated for this attribute
551  */
552 static int ocs_add_delimiter(void *curr, int remaining)
553 {
554  if (remaining < 8)
555  return -1;
556  ocs_memset( curr, 0, 8);
557  return 8;
558 }
559 
560 /**
561  * @ingroup isns
562  * @brief Create a tag-length-value attribute
563  *
564  * This function will form a tag-length-value-attribute for the isns messages
565  *
566  * @param iscsi Pointer to the iSCSI structure that represents this device
567  * @param curr Pointer to the start of the attribute
568  * @param tag the tag of the attribute
569  * @param len the length of the attribute
570  * @param value Pointer to the value part of the attribute
571  * @param remaining the number of bytes left in the memory allocated for this msg
572  *
573  * @return returns the number of bytes allocated for this attribute
574  */
575 static int
576 ocs_add_tlv(ocs_iscsi_t *iscsi, void *curr, uint32_t tag, uint32_t len, void* value, int remaining)
577 {
578  uint32_t t, l;
579  int padsize = len & 3;
580  int push = 0;
581 
582  if (padsize != 0) {
583  padsize = 4 - padsize;
584  }
585  push = 2 * sizeof(uint32_t) + len + padsize;
586  if (remaining < push) {
587  return -1;
588  }
589  if (ocs_binary_attr(tag))
590  {
591  t = ocs_htobe32(tag);
592  ocs_memcpy(curr, &t, sizeof(uint32_t));
593  curr += sizeof(uint32_t);
594  l = ocs_htobe32(len + padsize) ;
595  ocs_memcpy(curr, &l, sizeof(uint32_t));
596  curr += sizeof(uint32_t);
597  switch (len) {
598  case 0:
599  break;
600  case 2:
601  *((uint16_t*)curr) = ocs_htobe16( * (uint16_t *) value);
602  break;
603  case 4:
604  *((uint32_t*)curr) = ocs_htobe32( * (uint32_t *) value);
605  break;
606  case 8:
607  *((uint64_t*)curr) = ocs_htobe64( * (uint64_t *) value);
608  break;
609  default:
610  ocs_log_test(iscsi->os, "Error: value attribute must be of size 2, 4, or 8 Bytes.\n");
611  return -1;
612  }
613  curr += len;
614  } else {
615  t = ocs_htobe32(tag);
616  ocs_memcpy(curr, &t, sizeof(uint32_t));
617  curr += sizeof(uint32_t);
618  l = ocs_htobe32(len + padsize);
619  ocs_memcpy(curr, &l, sizeof(uint32_t));
620  curr += sizeof(uint32_t);
621 
622  ocs_memcpy(curr, value, len);
623  curr += len;
624  }
625  if (padsize != 0)
626  {
627  ocs_memset(curr, 0, padsize);
628  curr += padsize;
629  }
630  return (push);
631 }
632 
633 /**
634  * @ingroup isns
635  * @brief Forms an v6-format ip string
636  *
637  * This function will convert an ip address into an ipv6-formatted string
638  *
639  * @param iscsi Pointer to the iSCSI structure that represents this device
640  * @param addr Pointer to the input ip address
641  * @param ret_addr Pointer to the return string
642  *
643  * @return none
644  */
645 static void
646 ocs_get_ipv6_string(ocs_iscsi_t *iscsi, ocs_ip_address_t *addr, uint8_t *ret_addr)
647 {
648  int i = 0;
649 
650  if ( addr->ip_type == OCS_IP_TYPE_V6 || addr->ip_type == OCS_IP_TYPE_AUTO_V6 ) {
651  ocs_memcpy(ret_addr, addr->ip_address, 16);
652  return;
653  }
654  /* map it to ipv6 format if it is ipv4 */
655  for(i = 0; i < 10; i++)
656  ret_addr[i] = 0x00;
657  ret_addr[10] = 0xff;
658  ret_addr[11] = 0xff;
659  for(i = 0; i < 4; i++)
660  ret_addr[12 + i] = addr->ip_address[i];
661  return ;
662 }
663 
664 /**
665  * @ingroup isns
666  * @brief Parses the flags of the response of an isns message
667  *
668  * @param iscsi Pointer to the iSCSI structure that represents this device
669  * @param flags The flags of that message
670  */
671 static void
672 ocs_parse_flags(ocs_iscsi_t *iscsi, uint16_t flags)
673 {
674  ocs_print_nl(iscsi, 2);
675  ocs_isns_log(iscsi->os, "\t\t\tParsing flags (0x%x)of the response message\n", flags);
676 
677  if (flags >> 2 & 1) {
678  ocs_isns_log(iscsi->os, "First PDU in the message\n");
679  } else {
680  ocs_isns_log(iscsi->os, "Not first PDU in the message\n");
681  }
682  if (flags >> 3 & 1) {
683  ocs_isns_log(iscsi->os, "Last PDU in the message\n");
684  } else {
685  ocs_isns_log(iscsi->os, "Not last PDU in the message\n");
686  }
687  if (flags >> 4 & 1) {
688  ocs_isns_log(iscsi->os, "Replace bit = true\n");
689  } else {
690  ocs_isns_log(iscsi->os, "Replace bit = false\n");
691  }
692  if (flags >> 5 & 1) {
693  ocs_isns_log(iscsi->os, "Authentication Block = true\n");
694  } else {
695  ocs_isns_log(iscsi->os, "No Authentication Block\n");
696  }
697  if (flags >> 6 & 1) {
698  ocs_isns_log(iscsi->os, "Sender is a server\n");
699  } else {
700  ocs_isns_log(iscsi->os, "Sender is NOT a server\n");
701  }
702  if (flags >> 7 & 1) {
703  ocs_isns_log(iscsi->os, "Sender is a client\n");
704  } else {
705  ocs_isns_log(iscsi->os, "Sender is NOT a client\n");
706  }
707 }
708 
709 /**
710  * @ingroup isns
711  * @brief Parses the header of the response of an isns message
712  *
713  * @param iscsi Pointer to the iSCSI structure that represents this device
714  * @param rsp Pointer to the header of the response message
715  */
716 static void
717 ocs_parse_rsp_hdr(ocs_iscsi_t *iscsi, void *rsp)
718 {
719  uint16_t version, func_id, payload_len, flags, transaction_id, sequence_id;
720 
721  //ocs_print_nl(iscsi, 2);
722  ocs_isns_log(iscsi->os, "\t\t\tISNS: PARSING THE HEADER OF THE RSP MSG\n");
723 
724  ocs_memcpy(&version, rsp, 2);
725  rsp += 2;
726 
727  ocs_memcpy(&func_id, rsp, 2);
728  rsp += 2;
729 
730  ocs_memcpy(&payload_len, rsp, 2);
731  rsp += 2;
732 
733  ocs_memcpy(&flags, rsp, 2);
734  rsp += 2;
735 
736  ocs_memcpy(&transaction_id, rsp, 2);
737  rsp += 2;
738 
739  ocs_memcpy(&sequence_id, rsp, 2);
740  rsp += 2;
741 
742  ocs_isns_log(iscsi->os, "version is (%x) \n", ocs_be16toh(version));
743  ocs_isns_log(iscsi->os, "func_id is (%d) \n", ocs_be16toh(func_id));
744  ocs_isns_log(iscsi->os, "payload_len is (%d) \n", ocs_be16toh(payload_len));
745  ocs_isns_log(iscsi->os, "flags is (0x%x) \n", ocs_be16toh(flags));
746  ocs_isns_log(iscsi->os, "transaction_id is (%d) \n", ocs_be16toh(transaction_id));
747  ocs_isns_log(iscsi->os, "sequence_id is (%d) \n", ocs_be16toh(sequence_id));
748  ocs_parse_flags(iscsi, flags);
749  return;
750 }
751 
752 /**
753  * @ingroup isns
754  * @brief Parses the response of the DevAttrQry message
755  *
756  * @param iscsi Pointer to the iSCSI structure that represents this device
757  * @param rsp_ptr Pointer to the start of the response
758  * @param rsp_len the length of the response
759  * @param ret_nodes_count Pointer to the number of discovered targets
760  * @return returns Pointer to the table of the discovered registered targets, NULL if error
761  */
762 static void *
763 ocs_parse_qry_rsp(ocs_iscsi_t *iscsi, void *rsp_ptr, uint16_t rsp_len, uint16_t *ret_nodes_count)
764 {
765  uint32_t error_code = 0;
766  int16_t bytes_left = rsp_len;
767  uint32_t tag, len;
768  uint8_t counter = 0;
769  uint8_t delimiter_parsed = 0;
770  uint16_t v16;
771  uint32_t v32;
772  uint64_t v64;
773  void *void_v = NULL;
774  ocs_ip_type_e ip_type = OCS_IP_TYPE_V6;
775  char ip_addr[48];
776  uint16_t nodes_count = 0;
777  void *ret = NULL;
778  void *nodes_ptr = NULL;
779  uint16_t bleft = 0;
780 
781  ocs_print_nl(iscsi, 2);
782  ocs_isns_log(iscsi->os, "\t\t\tISNS: parse query resp\n");
783 
784  ocs_parse_rsp_hdr(iscsi, rsp_ptr);
785  bytes_left -= sizeof(isns_hdr_t);
786  rsp_ptr += sizeof(isns_hdr_t);
787 
788  ocs_print_nl(iscsi, 2);
789  ocs_isns_log(iscsi->os, "\t\t\tPARSING THE PDU OF THE RSP MSG\n");
790 
791  ocs_memcpy(&error_code, rsp_ptr, 4);
792  error_code = ocs_be32toh(error_code);
793  bytes_left -= 4;
794  rsp_ptr += 4;
795  //??need to check for Transaction id and seq id values.
796  if (error_code == 0) {
797  ocs_isns_log(iscsi->os, "error code = %d (SUCCESS!) \n", error_code);
798  } else {
799  ocs_log_test(iscsi->os, "FAILURE: ISNS Query Response Message has error code = %s (%d)\n", ocs_get_error_name(error_code), error_code);
800  return NULL;
801  }
802 
803  ocs_isns_log(iscsi->os, "PDU Length = %d\n", bytes_left + 4 ); // +4 bytes for the error code
804  ocs_print_nl(iscsi, 1);
805  ocs_isns_log(iscsi->os, "\t\t\tPRINTING PDU ATTRIBUTES IN THE QRY RSP MSG\n");
806  ocs_print_nl(iscsi, 1);
807  while (bytes_left > 0) {
808  counter++;
809 
810  ocs_memcpy(&tag, rsp_ptr, 4);
811  tag = ocs_be32toh(tag);
812  bytes_left -= 4;
813  rsp_ptr += 4;
814 
815  ocs_memcpy(&len, rsp_ptr, 4);
816  len = ocs_be32toh(len);
817  bytes_left -= 4;
818  rsp_ptr += 4;
819 
820  if (tag == ISNS_TAG_DELIMITER ) {
821  ocs_print_nl(iscsi, 1);
822  ocs_isns_log(iscsi->os, "********* DELIMITER *********\n");
823  delimiter_parsed = 1;
824  counter = 0;
825 
826  /* for the second loop */
827  nodes_ptr = rsp_ptr;
828  bleft = bytes_left;
829  } else if (delimiter_parsed ) {
830  ocs_print_nl(iscsi, 1);
831  ocs_isns_log(iscsi->os, "********* Operating Attribute #%d *********\n", counter);
832  } else {
833  ocs_print_nl(iscsi, 1);
834  ocs_isns_log(iscsi->os, "********* Message Key Attribute #%d *********\n", counter);
835  }
836 
837  ocs_isns_log(iscsi->os, "tag = %s (%d)\n", ocs_get_tag_name(tag), tag);
838  ocs_isns_log(iscsi->os, "length = %d\n", len);
839 
840  if (tag == ISNS_TAG_DELIMITER && len == 0 ) {
841  ocs_isns_log(iscsi->os, "value = NO VALUE (DELIMITER ATTR.)\n");
842  } else if (ocs_binary_attr(tag)) {
843  switch (len) {
844  case 0:
845  ocs_isns_log(iscsi->os, "value = NO VALUE! [Binary Attr but has length = 0]\n");
846  break;
847  case 2:
848  v16 = ocs_htobe16( * (uint16_t *) rsp_ptr);
849  ocs_isns_log(iscsi->os, "value (v16) = %d\n", v16);
850  break;
851  case 4:
852  v32 = ocs_htobe32( * (uint32_t *) rsp_ptr);
853  ocs_isns_log(iscsi->os, "value (v32) = %d\n", v32);
854  break;
855  case 8:
856  v64 = ocs_htobe64( * (uint64_t *) rsp_ptr);
857  ocs_isns_log(iscsi->os, "value (v64) = %" PRId64 " \n", v64);
858  break;
859  default:
860  ocs_log_test(iscsi->os, "Error: value attribute must be of size 2, 4, or 8 Bytes.\n");
861  return NULL;
862  }
863  } else if (tag == ISNS_TAG_PORTAL_IP_ADDRESS) {
864  format_ip_address(ip_type , rsp_ptr,
865  ip_addr, ARRAY_SIZE(ip_addr) );
866  ocs_isns_log(iscsi->os, "value (special) = %s\n", ip_addr);
867  } else {
868  void_v = ocs_malloc(iscsi->os, len, OCS_M_ZERO | OCS_M_NOWAIT);
869  if(void_v == NULL){
870  ocs_log_err(iscsi->os, "iSNS ERROR: Failed to allocate memory len %d\n", len);
871  return NULL;
872  }
873  ocs_memcpy(void_v, rsp_ptr, len);
874  ocs_isns_log(iscsi->os, "value (void) = %s\n", (char *) void_v);
875  ocs_free(iscsi->os, void_v, len);
876  void_v = NULL;
877  }
878  bytes_left -= len;
879  rsp_ptr += len;
880 
881  if(tag == ISNS_TAG_ISCSI_NAME) {
882  nodes_count++;
883  }
884  }
885 
886  ocs_print_nl(iscsi, 3);
887  if(nodes_count != 0) {
888  ocs_isns_log(iscsi->os, "nodes_count = %u\n", nodes_count);
889  *ret_nodes_count = nodes_count;
890  /* second loop: create nodes */
891  ret = ocs_malloc(iscsi->os, nodes_count * sizeof(ocs_isns_node_t), OCS_M_ZERO | OCS_M_NOWAIT);
892  if(ret == NULL){
893  ocs_log_err(iscsi->os, "iSNS ERROR: Failed to allocate memory, nodes_count %d\n",
894  nodes_count);
895  return NULL;
896  }
897  if(ocs_create_nodes(iscsi, nodes_ptr, bleft, ret) != 0){
898  ocs_log_err(iscsi->os, "Error: can't create nodes\n");
899  ocs_free(iscsi->os, ret, nodes_count * sizeof(ocs_isns_node_t));
900  return NULL;
901  }
902  /* third loop: fill those nodes */
903  ocs_fill_nodes_values(iscsi, nodes_ptr, bleft, ret);
904  } else {
905  ocs_isns_log(iscsi->os, "No second loop as nodes_count = 0\n");
906  return NULL;
907  }
908  return ret;
909 }
910 
911 /**
912  * @ingroup isns
913  * @brief Sends the DevAttrReg message to the iSNS server.
914  *
915  * This function will query the iSCSI device with
916  * the isns server to get all the registered targets
917  *
918  * @param iscsi Pointer to the iSCSI structure that represents this device
919  * @param isns_ip Pointer to the IP address of the iSNS server
920  * @param ret_nodes_count Pointer to the number of nodes registered
921  *
922  * @return Pointer to the table of the discovered registered targets
923  */
924 void *
925 ocs_isns_qry_tgts(ocs_iscsi_t *iscsi, ocs_ip_address_t *isns_ip, uint16_t *ret_nodes_count)
926 {
927  ocs_t *ocs = iscsi->os;
928  void *msg_ptr = NULL;
929  void *current_ptr = NULL;
930  char *iscsi_name;
931  char ip_addr[48];
932  int bytes_added = 0;
933  uint32_t payload_len = 0;
934  int32_t rc;
935  uint32_t msg_len;
936  ocs_ip_address_t *ip_addr_struct;
937  uint32_t node_type = 0x00000001;
938  void *ret_ptr = NULL;
939 
940  msg_ptr = ocs_malloc(ocs, PDU_MEM_SIZE, OCS_M_ZERO | OCS_M_NOWAIT);
941  if(msg_ptr == NULL){
942  ocs_log_err(iscsi->os, "iSNS ERROR: Failed to allocate memory\n");
943  return NULL;
944  }
945  current_ptr = msg_ptr + sizeof(isns_hdr_t);
946 
947  iscsi_name = ocs_iscsi_tgt_get_names(ocs, 0);
948  if(iscsi_name == NULL){
949  ocs_log_test(iscsi->os, "iSNS ERROR: Failed to get iSCSI name\n");
950  ocs_free(iscsi->os, msg_ptr, PDU_MEM_SIZE);
951  return NULL;
952  }
953  ip_addr_struct = ocs_iscsi_tgt_get_ip_address(ocs, iscsi_name, 0);
954  if(ip_addr_struct == NULL){
955  ocs_log_test(iscsi->os, "iSNS ERROR: Failed to get ip address\n");
956  ocs_free(iscsi->os, msg_ptr, PDU_MEM_SIZE);
957  return NULL;
958  }
959  format_ip_address(ip_addr_struct->ip_type , ip_addr_struct->ip_address,
960  ip_addr, ARRAY_SIZE(ip_addr) );
961  ocs_print_nl(iscsi, 2);
962  ocs_isns_log(iscsi->os, "\t\t\tiSNS query tgts begin\n");
963  ocs_isns_log(iscsi->os, "***iscsi name is (%s) \n", iscsi_name);
964  ocs_isns_log(iscsi->os, "***its length=%d Bytes\n", (int) ocs_strlen(iscsi_name));
965 
966  ocs_print_nl(iscsi, 1);
967  ocs_isns_log(iscsi->os, "\t\t\tForming the PDU (adding tlv attrs)\n");
968  ocs_print_nl(iscsi, 1);
969 
970  //1-src attr =iscsi name
971  bytes_added = ocs_add_tlv(&ocs->iscsi, current_ptr, ISNS_TAG_ISCSI_NAME, ocs_strlen(iscsi_name),
972  iscsi_name, PDU_MEM_SIZE - (msg_ptr - current_ptr) );
973  if (bytes_added <= 0) {
974  ocs_log_test(iscsi->os, "Error: Insufficient Space for the PDU Attributes\n");
975  ocs_free(iscsi->os, msg_ptr, PDU_MEM_SIZE);
976  return NULL;
977  }
978  current_ptr += bytes_added;
979  ocs_isns_log(iscsi->os, "1- iSCSI name added, current_ptr moved %d bytes\n",
980  bytes_added);
981 
982  //2- iSCSI Node Type
983  bytes_added = ocs_add_tlv(&ocs->iscsi, current_ptr, ISNS_TAG_ISCSI_NODE_TYPE, sizeof(uint32_t), &node_type,
984  PDU_MEM_SIZE - (msg_ptr - current_ptr) );
985  if (bytes_added <= 0) {
986  ocs_log_test(iscsi->os, "Error: Insufficient Space for the PDU Attributes\n");
987  ocs_free(iscsi->os, msg_ptr, PDU_MEM_SIZE);
988  return NULL;
989  }
990  current_ptr += bytes_added;
991  ocs_isns_log(iscsi->os, "2- iSCSI node type added, current_ptr moved %d bytes\n",
992  bytes_added);
993 
994  //3- delimiterc
995  bytes_added = ocs_add_delimiter(current_ptr, PDU_MEM_SIZE - (msg_ptr - current_ptr) );
996  if (bytes_added <= 0) {
997  ocs_log_test(iscsi->os, "Error: Insufficient Space for the PDU Attributes\n");
998  ocs_free(iscsi->os, msg_ptr, PDU_MEM_SIZE);
999  return NULL;
1000  }
1001  current_ptr += bytes_added;
1002  ocs_isns_log(iscsi->os, "3- delimiter added, current_ptr moved %d bytes\n",
1003  bytes_added);
1004 
1005  //empty attrs: ip addr, port, and iscsi name
1006  //4- portal ip address
1007  bytes_added = ocs_add_tlv(&ocs->iscsi, current_ptr, ISNS_TAG_PORTAL_IP_ADDRESS, 0, NULL,
1008  PDU_MEM_SIZE - (msg_ptr - current_ptr) );
1009  if (bytes_added <= 0) {
1010  ocs_log_test(iscsi->os, "Error: Insufficient Space for the PDU Attributes\n");
1011  ocs_free(iscsi->os, msg_ptr, PDU_MEM_SIZE);
1012  return NULL;
1013  }
1014  current_ptr += bytes_added;
1015  ocs_isns_log(iscsi->os, "6- (EMPTY) portal ip address (%s) added, current_ptr moved %d bytes\n",
1016  ip_addr, bytes_added);
1017 
1018  //5- portal TCP Port
1019  bytes_added = ocs_add_tlv(&ocs->iscsi, current_ptr, ISNS_TAG_PORTAL_TCP_PORT, 0, NULL,
1020  PDU_MEM_SIZE - (msg_ptr - current_ptr) );
1021  if (bytes_added <= 0) {
1022  ocs_log_test(iscsi->os, "Error: Insufficient Space for the PDU Attributes\n");
1023  ocs_free(iscsi->os, msg_ptr, PDU_MEM_SIZE);
1024  return NULL;
1025  }
1026  current_ptr += bytes_added;
1027  ocs_isns_log(iscsi->os, "7- (EMPTY) portal TCP port added, current_ptr moved %d bytes\n",
1028  bytes_added);
1029 
1030  //6- iscsi name
1031  bytes_added = ocs_add_tlv(&ocs->iscsi, current_ptr, ISNS_TAG_ISCSI_NAME, 0, NULL,
1032  PDU_MEM_SIZE - (msg_ptr - current_ptr) );
1033  if (bytes_added <= 0) {
1034  ocs_log_test(iscsi->os, "Error: Insufficient Space for the PDU Attributes\n");
1035  ocs_free(iscsi->os, msg_ptr, PDU_MEM_SIZE);
1036  return NULL;
1037  }
1038  current_ptr += bytes_added;
1039  ocs_isns_log(iscsi->os, "8- (EMPTY) iSCSI name added, current_ptr moved %d bytes\n",
1040  bytes_added);
1041 
1042 
1043  payload_len = current_ptr - msg_ptr - sizeof(isns_hdr_t);
1044  msg_len = payload_len + sizeof(isns_hdr_t);
1045  ocs_print_nl(iscsi, 1);
1046  ocs_isns_log(iscsi->os, "payload_len= %u, nmsg_len= %u\n", payload_len, msg_len);
1047 
1048  //0- build and add the header of the DevAttrQuery
1049  bytes_added = ocs_build_hdr_dev_attr_qry(msg_ptr, (uint16_t) payload_len);
1050  if (bytes_added != 12) {
1051  ocs_log_test(iscsi->os, "EROR: ISNS error in building the header of the message\n");
1052  ocs_free(iscsi->os, msg_ptr, PDU_MEM_SIZE);
1053  return NULL;
1054  }
1055  ocs_isns_log(iscsi->os , "size of header is: %d\n", (int) sizeof(isns_hdr_t) );
1056  ocs_isns_log(iscsi->os, "\t\t\tI WILL SEND NOW!\n");
1057  rc = ocs_iscsi_isns_send(ocs, isns_ip,
1058  3205, // tcp port
1059  msg_ptr,
1060  &msg_len,
1061  PDU_MEM_SIZE);
1062 
1063  if (rc == 0) {
1064  ocs_isns_log(ocs, "iSNS Send Sent, received %d bytes\n",
1065  msg_len);
1066  if (msg_len > 0) {
1067  ret_ptr = ocs_parse_qry_rsp(&ocs->iscsi, msg_ptr, msg_len, ret_nodes_count);
1068  if(ret_ptr == NULL){
1069  ocs_log_test(iscsi->os, "EROR: ISNS error in parsing the query response\n");
1070  ocs_free(iscsi->os, msg_ptr, PDU_MEM_SIZE);
1071  return NULL;
1072  }
1073  }
1074  } else {
1075  ocs_isns_log(ocs, "iSNS Send failed with rc %d\n",
1076  rc);
1077  }
1078  ocs_free(iscsi->os, msg_ptr, PDU_MEM_SIZE);
1079  ocs_print_nl(iscsi, 2);
1080  ocs_isns_log(iscsi->os, "\t\t\tEND OF ISNS FUNCTION\n");
1081  ocs_isns_log(iscsi->os, "==============================================================================\n");
1082  return ret_ptr;
1083 }
1084 
1085 /**
1086  * @ingroup isns
1087  * @brief Parses the response of an isns message
1088  *
1089  * This function will create an empty isns node and allocates memory for
1090  * the given number of ip_port structs
1091  *
1092  * @param iscsi Pointer to the iSCSI structure that represents this device
1093  * @param original_func_name Pointer to the name of the source message
1094  * @param rsp_ptr Pointer to the response
1095  * @param rsp_len The length of that response
1096  * @param reg_period Pointer to the registration period variable
1097  * @param eid The entity ID assigned by the iSNS server during registration
1098  *
1099  * @return returns 0 if successful, negative otherwise
1100  */
1101 static int8_t
1102 ocs_parse_msg_rsp(ocs_iscsi_t *iscsi, const char *original_func_name, void *rsp_ptr, uint16_t rsp_len, uint32_t *reg_period, char * eid)
1103 {
1104  uint32_t error_code = 0;
1105  int16_t bytes_left = rsp_len;
1106  uint32_t tag, len;
1107  uint8_t counter = 0;
1108  uint8_t delimiter_parsed = 0;
1109  uint16_t v16;
1110  uint32_t v32 = 0;
1111  uint64_t v64;
1112  void *void_v = NULL;
1113  ocs_ip_type_e ip_type = OCS_IP_TYPE_V6;
1114  char ip_addr[48];
1115 
1116  ocs_print_nl(iscsi, 2);
1117  ocs_isns_log(iscsi->os, "\t\t\tiSNS parse msg resp\n");
1118 
1119  ocs_parse_rsp_hdr(iscsi, rsp_ptr);
1120  bytes_left -= sizeof(isns_hdr_t);
1121  rsp_ptr += sizeof(isns_hdr_t);
1122 
1123  ocs_print_nl(iscsi, 2);
1124  ocs_isns_log(iscsi->os, "\t\t\tPARSING THE PDU OF THE RSP of the %s MSG\n", original_func_name);
1125 
1126  ocs_memcpy(&error_code, rsp_ptr, 4);
1127  error_code = ocs_be32toh(error_code);
1128  bytes_left -= 4;
1129  rsp_ptr += 4;
1130  //??need to check for Transaction id and seq id values.
1131  if (error_code == 0) {
1132  ocs_isns_log(iscsi->os, "error code = %d (SUCCESS!) \n", error_code);
1133  } else {
1134  ocs_log_test(iscsi->os, "FAILURE: Response Message of the %s function has error code = %s (%d)\n", original_func_name, ocs_get_error_name(error_code), error_code);
1135  return -1;
1136  }
1137 
1138 
1139  ocs_isns_log(iscsi->os, "PDU Length = %d\n", bytes_left + 4 ); // +4 bytes for the error code
1140  ocs_print_nl(iscsi, 1);
1141  ocs_isns_log(iscsi->os, "\t\t\tPRINTING PDU ATTRIBUTES\n");
1142  ocs_print_nl(iscsi, 1);
1143  while (bytes_left > 0) {
1144  counter++;
1145 
1146  ocs_memcpy(&tag, rsp_ptr, 4);
1147  tag = ocs_be32toh(tag);
1148  bytes_left -= 4;
1149  rsp_ptr += 4;
1150 
1151  ocs_memcpy(&len, rsp_ptr, 4);
1152  len = ocs_be32toh(len);
1153  bytes_left -= 4;
1154  rsp_ptr += 4;
1155  if (tag == ISNS_TAG_DELIMITER ) {
1156  ocs_print_nl(iscsi, 1);
1157  ocs_isns_log(iscsi->os, "********* DELIMITER *********\n");
1158  delimiter_parsed = 1;
1159  counter = 0;
1160  } else if (delimiter_parsed ) {
1161  ocs_print_nl(iscsi, 1);
1162  ocs_isns_log(iscsi->os, "********* Operating Attribute #%d *********\n", counter);
1163  } else {
1164  ocs_print_nl(iscsi, 1);
1165  ocs_isns_log(iscsi->os, "********* Message Key Attribute #%d *********\n", counter);
1166  }
1167 
1168  ocs_isns_log(iscsi->os, "tag = %s (%d)\n", ocs_get_tag_name(tag), tag);
1169  ocs_isns_log(iscsi->os, "length = %d\n", len);
1170 
1171  if (tag == ISNS_TAG_DELIMITER && len == 0 ) {
1172  ocs_isns_log(iscsi->os, "value = NO VALUE (DELIMITER ATTR.)\n");
1173  } else if (ocs_binary_attr(tag)) {
1174  switch (len) {
1175  case 0:
1176  ocs_isns_log(iscsi->os, "value = NO VALUE! [Binary Attr but has length = 0]\n");
1177  break;
1178  case 2:
1179  v16 = ocs_htobe16( * (uint16_t *) rsp_ptr);
1180  ocs_isns_log(iscsi->os, "value (v16) = %d\n", v16);
1181  break;
1182  case 4:
1183  v32 = ocs_htobe32( * (uint32_t *) rsp_ptr);
1184  ocs_isns_log(iscsi->os, "value (v32) = %d\n", v32);
1185  break;
1186  case 8:
1187  v64 = ocs_htobe64( * (uint64_t *) rsp_ptr);
1188  ocs_isns_log(iscsi->os, "value (v64) = %" PRId64 "\n", v64);
1189  break;
1190  default:
1191  ocs_log_test(iscsi->os, "Error: value attribute must be of size 2, 4, or 8 Bytes.\n");
1192  return -2;
1193  }
1194  } else if (tag == ISNS_TAG_PORTAL_IP_ADDRESS) {
1195  format_ip_address(ip_type , rsp_ptr,
1196  ip_addr, ARRAY_SIZE(ip_addr) );
1197  ocs_isns_log(iscsi->os, "value (special) = %s\n", ip_addr);
1198  } else {
1199  void_v = ocs_malloc(iscsi->os, len, OCS_M_ZERO | OCS_M_NOWAIT);
1200  if(void_v == NULL){
1201  ocs_log_err(iscsi->os, "iSNS ERROR: Failed to allocate memory len %d\n", len);
1202  return -1;
1203  }
1204  ocs_memcpy(void_v, rsp_ptr, len);
1205  ocs_isns_log(iscsi->os, "value (void) = %s\n", (char *) void_v);
1206  ocs_free(iscsi->os, void_v, len);
1207 
1208  if(tag == ISNS_TAG_ENTITY_IDENTIFIER){
1209  ocs_print_nl(iscsi, 10);
1210  ocs_memcpy(eid, rsp_ptr, len);
1211  }
1212  }
1213  if(tag == ISNS_TAG_REG_PERIOD) {
1214  *reg_period = v32;
1215  }
1216  bytes_left -= len;
1217  rsp_ptr += len;
1218  //ocs_isns_log(iscsi->os, "Bytes left = %d\n", bytes_left);
1219  }
1220  return 0;
1221 }
1222 
1223 /**
1224  * @ingroup isns
1225  * @brief Sends the DevAttrReg message to the iSNS server.
1226  *
1227  * This function will query the iSCSI device with
1228  * the isns server to get all the registered targets
1229  *
1230  * @param iscsi Pointer to the iSCSI structure that represents this device
1231  * @param isns_ip Pointer to the IP address of the iSNS server
1232  *
1233  * @return Pointer to the table of the discovered registered targets
1234  */
1235 static void *
1237 {
1238  ocs_t *ocs = iscsi->os;
1239  void *msg_ptr = NULL;
1240  void *current_ptr = NULL;
1241  char *iscsi_name;
1242  char ip_addr[48];
1243  int bytes_added = 0;
1244  uint32_t payload_len = 0;
1245  int32_t rc;
1246  uint32_t msg_len;
1247  ocs_ip_address_t *ip_addr_struct;
1248  uint32_t node_type = 0x00000001;
1249  void *ret_ptr = NULL;
1250  uint32_t nodes_index = 0;
1251  uint16_t *ret_nodes_count = NULL;
1252 
1253  msg_ptr = ocs_malloc(ocs, PDU_MEM_SIZE, OCS_M_ZERO | OCS_M_NOWAIT);
1254  if(msg_ptr == NULL){
1255  ocs_log_test(iscsi->os, "iSNS ERROR: Failed to allocate memory\n");
1256  return NULL;
1257  }
1258  current_ptr = msg_ptr + sizeof(isns_hdr_t);
1259 
1260  ocs_isns_log(iscsi->os, "\t\t\tiSNS query attr begin\n");
1261  iscsi_name = ocs_iscsi_tgt_get_names(ocs, nodes_index);
1262  while(iscsi_name) {
1263  current_ptr = msg_ptr + sizeof(isns_hdr_t);
1264  ip_addr_struct = ocs_iscsi_tgt_get_ip_address(ocs, iscsi_name, 0);
1265  if(ip_addr_struct == NULL) {
1266  ocs_log_test(iscsi->os, "iSNS ERROR: Failed to get ip address\n");
1267  ocs_free(iscsi->os, msg_ptr, PDU_MEM_SIZE);
1268  return NULL;
1269  }
1270  format_ip_address(ip_addr_struct->ip_type , ip_addr_struct->ip_address,
1271  ip_addr, ARRAY_SIZE(ip_addr) );
1272  ocs_print_nl(iscsi, 2);
1273  ocs_isns_log(iscsi->os, "***iscsi name #%u is (%s) \n", nodes_index, iscsi_name);
1274  ocs_isns_log(iscsi->os, "***its length=%d Bytes\n", (int) ocs_strlen(iscsi_name));
1275 
1276  ocs_print_nl(iscsi, 1);
1277  ocs_isns_log(iscsi->os, "\t\t\tForming the PDU (adding tlv attrs)\n");
1278  ocs_print_nl(iscsi, 1);
1279 
1280  //1-src attr =iscsi name
1281  bytes_added = ocs_add_tlv(&ocs->iscsi, current_ptr, ISNS_TAG_ISCSI_NAME, ocs_strlen(iscsi_name),
1282  iscsi_name, PDU_MEM_SIZE - (msg_ptr - current_ptr) );
1283  if (bytes_added <= 0) {
1284  ocs_log_test(iscsi->os, "Error: Insufficient Space for the PDU Attributes\n");
1285  ocs_free(iscsi->os, msg_ptr, PDU_MEM_SIZE);
1286  return NULL;
1287  }
1288  current_ptr += bytes_added;
1289  ocs_isns_log(iscsi->os, "1- iSCSI name added, current_ptr moved %d bytes\n",
1290  bytes_added);
1291 
1292  //2- iSCSI Node Type
1293  bytes_added = ocs_add_tlv(&ocs->iscsi, current_ptr, ISNS_TAG_ISCSI_NODE_TYPE, sizeof(uint32_t), &node_type,
1294  PDU_MEM_SIZE - (msg_ptr - current_ptr) );
1295  if (bytes_added <= 0) {
1296  ocs_log_test(iscsi->os, "Error: Insufficient Space for the PDU Attributes\n");
1297  ocs_free(iscsi->os, msg_ptr, PDU_MEM_SIZE);
1298  return NULL;
1299  }
1300  current_ptr += bytes_added;
1301  ocs_isns_log(iscsi->os, "2- iSCSI node type added, current_ptr moved %d bytes\n",
1302  bytes_added);
1303 
1304  //3- delimiter
1305  bytes_added = ocs_add_delimiter(current_ptr, PDU_MEM_SIZE - (msg_ptr - current_ptr) );
1306  if (bytes_added <= 0) {
1307  ocs_log_test(iscsi->os, "Error: Insufficient Space for the PDU Attributes\n");
1308  ocs_free(iscsi->os, msg_ptr, PDU_MEM_SIZE);
1309  return NULL;
1310  }
1311  current_ptr += bytes_added;
1312  ocs_isns_log(iscsi->os, "3- delimiter added, current_ptr moved %d bytes\n",
1313  bytes_added);
1314 
1315  //empty Alias to query it
1316  bytes_added = ocs_add_tlv(&ocs->iscsi, current_ptr, ISNS_TAG_ISCSI_ALIAS, 0, NULL,
1317  PDU_MEM_SIZE - (msg_ptr - current_ptr) );
1318  if (bytes_added <= 0) {
1319  ocs_log_test(iscsi->os, "Error: Insufficient Space for the PDU Attributes\n");
1320  ocs_free(iscsi->os, msg_ptr, PDU_MEM_SIZE);
1321  return NULL;
1322  }
1323  current_ptr += bytes_added;
1324  ocs_isns_log(iscsi->os, "-- (EMPTY) Alias added, current_ptr moved %d bytes\n",
1325  bytes_added);
1326 
1327 
1328  payload_len = current_ptr - msg_ptr - sizeof(isns_hdr_t);
1329  msg_len = payload_len + sizeof(isns_hdr_t);
1330  ocs_print_nl(iscsi, 1);
1331  ocs_isns_log(iscsi->os, "payload_len= %u, nmsg_len= %u\n", payload_len, msg_len);
1332 
1333  //0- build and add the header of the DevAttrQuery
1334  bytes_added = ocs_build_hdr_dev_attr_qry(msg_ptr, (uint16_t) payload_len);
1335  if (bytes_added != 12) {
1336  ocs_log_test(iscsi->os, "ERROR: ISNS error in building the header of the message\n");
1337  ocs_free(iscsi->os, msg_ptr, PDU_MEM_SIZE);
1338  return NULL;
1339  }
1340  ocs_isns_log(iscsi->os , "size of header is: %d\n", (int) sizeof(isns_hdr_t) );
1341  ocs_isns_log(iscsi->os, "\t\t\tI WILL SEND NOW!\n");
1342  rc = ocs_iscsi_isns_send(ocs, isns_ip,
1343  3205, // tcp port
1344  msg_ptr,
1345  &msg_len,
1346  PDU_MEM_SIZE);
1347 
1348  if (rc == 0) {
1349  ocs_isns_log(ocs, "iSNS Send Sent, received %d bytes\n", msg_len);
1350  if (msg_len > 0) {
1351  ret_ptr = ocs_parse_qry_rsp(&ocs->iscsi, msg_ptr, msg_len, ret_nodes_count);
1352  if(ret_ptr == NULL){
1353  ocs_log_test(iscsi->os, "EROR: ISNS: error in parsing the query response\n");
1354  ocs_free(iscsi->os, msg_ptr, PDU_MEM_SIZE);
1355  return NULL;
1356  }
1357  }
1358  } else {
1359  ocs_isns_log(ocs, "iSNS Send failed with rc %d\n", rc);
1360  }
1361  if(ret_ptr == NULL) {
1362  ocs_log_test(ocs, "FAILED at index %u !\n", nodes_index);
1363  }
1364  ocs_print_nl(iscsi, 2);
1365  nodes_index++;
1366  iscsi_name = ocs_iscsi_tgt_get_names(ocs, nodes_index);
1367  }
1368  ocs_free(iscsi->os, msg_ptr, PDU_MEM_SIZE);
1369  ocs_print_nl(iscsi, 2);
1370  ocs_isns_log(iscsi->os, "\t\t\tEND OF ISNS FUNCTION\n");
1371  ocs_isns_log(iscsi->os, "==============================================================================\n");
1372 
1373  return ret_ptr;
1374 }
1375 
1376 /**
1377  * @brief Sends a query to an ISNS target to keep it alive
1378  *
1379  * This function sends a query to the disovered targets to keep them alive (if ESI is no present)
1380  *
1381  * @param arg Pointer to the ocs structure
1382  *
1383  */
1384 static void
1386  ocs_t *ocs = (ocs_t *) arg;
1387  uint32_t cycle_period = ocs->iscsi.isns_reg_period;
1388  void *qry_rsp_ptr = NULL;
1389 
1390  ocs_isns_log(ocs, "cycle_period = %u msec.\n", cycle_period);
1391  qry_rsp_ptr = ocs_isns_qry_attr(&ocs->iscsi, &ocs->iscsi.isns_ip);
1392  if(qry_rsp_ptr == NULL) {
1393  ocs_log_debug(ocs, "iSNS ERROR: ISNS ATTR QRY FAILED! but wont return\n");
1394  //return;
1395  }
1396  cycle_period = 20 * 1000;
1397  ocs_setup_timer(ocs, &ocs->iscsi.isns_timer,
1399  ocs,
1400  cycle_period, false);
1401  return;
1402 }
1403 
1404 /**
1405  * @ingroup isns
1406  * @brief Sends the DevAttrReg message to the iSNS server.
1407  *
1408  * This function will register all targets in this iSCSI device with
1409  * the isns server.
1410  *
1411  * @param iscsi Pointer to the iSCSI structure that represents this device
1412  * @param reg_tgts to determine whether to register targets or not
1413  * @param reg_ini to determine whether to register initiators or not
1414  * @param isns_ip Pointer to the IP address of the iSNS server
1415  * @param eid The entity ID assigned by the iSNS server during registration
1416  *
1417  * @return returns zero if successful, negative otherwise
1418  */
1419 int8_t
1420 ocs_isns_register(ocs_iscsi_t *iscsi, uint8_t reg_tgts, uint8_t reg_ini, ocs_ip_address_t *isns_ip, char *eid)
1421 {
1422  ocs_t *ocs = iscsi->os;
1423  void *msg_ptr = NULL;
1424  void *current_ptr = NULL;
1425  char *iscsi_name;
1426  char ip_addr[48];
1427  char *alias;
1428  int bytes_added = 0;
1429  uint32_t payload_len = 0;
1430  int32_t rc;
1431  uint32_t msg_len;
1432  ocs_ip_address_t *ip_addr_struct;
1433  uint32_t node_type = 0x00000001;
1434  uint32_t tcp_port = OCS_ISCSI_TCP_PORT;
1435  uint32_t iscsi_prtcl = ISCSI_PROTOCOL;
1436  uint32_t esi_interval = ISNS_ESI_INTERVAL;
1437  uint32_t esi_port = ISNS_ESI_PORT;
1438  uint8_t ipv6_addr[16];
1439  uint32_t ctr = 0;
1440  uint32_t index = 0;
1441  uint32_t reg_period = 0;
1442  uint32_t cycle_period;
1443 
1444  ocs_print_nl(iscsi, 2);
1445  ocs_isns_log(iscsi->os, "\t\t\tiSNS register function begin with index = %u\n", index);
1446 
1447  msg_ptr = ocs_malloc(ocs, PDU_MEM_SIZE, OCS_M_ZERO | OCS_M_NOWAIT);
1448  if(msg_ptr == NULL){
1449  ocs_log_err(iscsi->os, "iSNS ERROR: Failed to allocate memory\n");
1450  return -1;
1451  }
1452  current_ptr = msg_ptr + sizeof(isns_hdr_t);
1453 
1454  /* the tgts part */
1455  if(reg_tgts) {
1456  ocs_isns_log(iscsi->os, "\t\t\tSTART OF ISNS tgts part\n");
1457  iscsi_name = ocs_iscsi_tgt_get_names(ocs, index);
1458  alias = ocs_iscsi_tgt_get_alias(ocs, index);
1459 
1460  ocs_print_nl(iscsi, 1);
1461  ocs_isns_log(iscsi->os, "\t\t\tForming the PDU (adding tlv attrs)\n");
1462  ocs_print_nl(iscsi, 1);
1463  //1-src attr =iscsi name
1464  bytes_added = ocs_add_tlv(&ocs->iscsi, current_ptr, ISNS_TAG_ISCSI_NAME, ocs_strlen(iscsi_name),
1465  iscsi_name, PDU_MEM_SIZE - (msg_ptr - current_ptr) );
1466  if (bytes_added <= 0) {
1467  ocs_log_test(iscsi->os, "Error: Insufficient Space for the PDU Attributes\n");
1468  ocs_free(iscsi->os, msg_ptr, PDU_MEM_SIZE);
1469  return -1;
1470  }
1471  current_ptr += bytes_added;
1472  ocs_isns_log(iscsi->os, "1- iSCSI name added, current_ptr moved %d bytes\n",
1473  bytes_added);
1474 
1475  //2- key attr (EID but empty in our case)
1476  bytes_added = ocs_add_tlv(&ocs->iscsi, current_ptr, ISNS_TAG_ENTITY_IDENTIFIER, 0, NULL,
1477  PDU_MEM_SIZE - (msg_ptr - current_ptr) );
1478  if (bytes_added <= 0) {
1479  ocs_log_test(iscsi->os, "Error: Insufficient Space for the PDU Attributes\n");
1480  ocs_free(iscsi->os, msg_ptr, PDU_MEM_SIZE);
1481  return -1;
1482  }
1483  current_ptr += bytes_added;
1484  ocs_isns_log(iscsi->os, "2- MSG Key attr (EID but empty in our case), current_ptr moved %d bytes\n",
1485  bytes_added);
1486 
1487  //3- delimiter
1488  bytes_added = ocs_add_delimiter(current_ptr, PDU_MEM_SIZE - (msg_ptr - current_ptr) );
1489  if (bytes_added <= 0) {
1490  ocs_log_test(iscsi->os, "Error: Insufficient Space for the PDU Attributes\n");
1491  ocs_free(iscsi->os, msg_ptr, PDU_MEM_SIZE);
1492  return -1;
1493  }
1494  current_ptr += bytes_added;
1495  ocs_isns_log(iscsi->os, "3- delimiter added, current_ptr moved %d bytes\n",
1496  bytes_added);
1497 
1498 
1499  //4- no EID
1500  bytes_added = ocs_add_tlv(&ocs->iscsi, current_ptr, ISNS_TAG_ENTITY_IDENTIFIER, 0, NULL,
1501  PDU_MEM_SIZE - (msg_ptr - current_ptr) );
1502  if (bytes_added <= 0) {
1503  ocs_log_test(iscsi->os, "Error: Insufficient Space for the PDU Attributes\n");
1504  ocs_free(iscsi->os, msg_ptr, PDU_MEM_SIZE);
1505  return -1;
1506  }
1507  current_ptr += bytes_added;
1508  ocs_isns_log(iscsi->os, "4- (Empty) EID, current_ptr moved %d bytes\n",
1509  bytes_added);
1510 
1511 
1512  //5- protocol name (value of 2 means it is iSCSI protocol)
1513  bytes_added = ocs_add_tlv(&ocs->iscsi, current_ptr, ISNS_TAG_ENTITY_PROTOCOL, sizeof(uint32_t), &iscsi_prtcl,
1514  PDU_MEM_SIZE - (msg_ptr - current_ptr) );
1515  if (bytes_added <= 0) {
1516  ocs_log_test(iscsi->os, "Error: Insufficient Space for the PDU Attributes\n");
1517  ocs_free(iscsi->os, msg_ptr, PDU_MEM_SIZE);
1518  return -1;
1519  }
1520  current_ptr += bytes_added;
1521  ocs_isns_log(iscsi->os, "5- protocol name added, current_ptr moved %d bytes\n",
1522  bytes_added);
1523 
1524  //6- portal ip address
1525  ocs_isns_log(iscsi->os, "*****Multiple IP Addresses*****\n");
1526  ip_addr_struct = ocs_iscsi_tgt_get_ip_address(ocs, iscsi_name, ctr);
1527  while (ip_addr_struct) {
1528  format_ip_address(ip_addr_struct->ip_type , ip_addr_struct->ip_address,
1529  ip_addr, ARRAY_SIZE(ip_addr) );
1530  ocs_get_ipv6_string(&ocs->iscsi, ip_addr_struct, ipv6_addr);
1531  ocs_isns_log(iscsi->os, "****ip_addr is (%s). its length=%d Bytes \n", ip_addr, (int) ocs_strlen(ip_addr));
1532  bytes_added = ocs_add_tlv(&ocs->iscsi, current_ptr, ISNS_TAG_PORTAL_IP_ADDRESS, sizeof(ipv6_addr), ipv6_addr,
1533  PDU_MEM_SIZE - (msg_ptr - current_ptr) );
1534  if (bytes_added <= 0) {
1535  ocs_log_test(iscsi->os, "Error: Insufficient Space for the PDU Attributes\n");
1536  ocs_free(iscsi->os, msg_ptr, PDU_MEM_SIZE);
1537  return -1;
1538  }
1539  current_ptr += bytes_added;
1540  ocs_isns_log(iscsi->os, "6- portal ip address (%s) added, current_ptr moved %d bytes\n",
1541  ip_addr, bytes_added);
1542 
1543 
1544  //7- portal TCP Port
1545  bytes_added = ocs_add_tlv(&ocs->iscsi, current_ptr, ISNS_TAG_PORTAL_TCP_PORT, sizeof(uint32_t), &tcp_port,
1546  PDU_MEM_SIZE - (msg_ptr - current_ptr) );
1547  if (bytes_added <= 0) {
1548  ocs_log_test(iscsi->os, "Error: Insufficient Space for the PDU Attributes\n");
1549  ocs_free(iscsi->os, msg_ptr, PDU_MEM_SIZE);
1550  return -1;
1551  }
1552  current_ptr += bytes_added;
1553  ocs_isns_log(iscsi->os, "7- portal TCP port added, current_ptr moved %d bytes\n",
1554  bytes_added);
1555 
1556  /* Only register for ESI on the DHCP address */
1557  if (ISNS_ENABLE_ESI && ip_addr_struct->ip_type == OCS_IP_TYPE_DHCP_V4) {
1558  //portal ESI interval
1559  bytes_added = ocs_add_tlv(&ocs->iscsi, current_ptr, ISNS_TAG_ESI_INTERVAL, sizeof(uint32_t), &esi_interval,
1560  PDU_MEM_SIZE - (msg_ptr - current_ptr) );
1561  if (bytes_added <= 0) {
1562  ocs_log_test(iscsi->os, "Error: Insufficient Space for the PDU Attributes\n");
1563  ocs_free(iscsi->os, msg_ptr, PDU_MEM_SIZE);
1564  return -1;
1565  }
1566  current_ptr += bytes_added;
1567  ocs_isns_log(iscsi->os, "7- ESI interval added, current_ptr moved %d bytes\n",
1568  bytes_added);
1569 
1570  //portal ESI Port
1571  bytes_added = ocs_add_tlv(&ocs->iscsi, current_ptr, ISNS_TAG_ESI_PORT, sizeof(uint32_t), &esi_port,
1572  PDU_MEM_SIZE - (msg_ptr - current_ptr) );
1573  if (bytes_added <= 0) {
1574  ocs_log_test(iscsi->os, "Error: Insufficient Space for the PDU Attributes\n");
1575  ocs_free(iscsi->os, msg_ptr, PDU_MEM_SIZE);
1576  return -1;
1577  }
1578  current_ptr += bytes_added;
1579  ocs_isns_log(iscsi->os, "7- ESI port added, current_ptr moved %d bytes\n",
1580  bytes_added);
1581  }
1582 
1583  ctr++;
1584  ip_addr_struct = ocs_iscsi_tgt_get_ip_address(ocs, iscsi_name, ctr);
1585  ocs_print_nl(iscsi, 1);
1586  }
1587 
1588 
1589 
1590  while(iscsi_name) {
1591  //8- iscsi name
1592  bytes_added = ocs_add_tlv(&ocs->iscsi, current_ptr, ISNS_TAG_ISCSI_NAME, ocs_strlen(iscsi_name), iscsi_name,
1593  PDU_MEM_SIZE - (msg_ptr - current_ptr) );
1594  if (bytes_added <= 0) {
1595  ocs_log_test(iscsi->os, "Error: Insufficient Space for the PDU Attributes\n");
1596  ocs_free(iscsi->os, msg_ptr, PDU_MEM_SIZE);
1597  return -1;
1598  }
1599  current_ptr += bytes_added;
1600  ocs_isns_log(iscsi->os, "8- iSCSI name added, current_ptr moved %d bytes\n",
1601  bytes_added);
1602 
1603  //9= iSCSI Node Type
1604  bytes_added = ocs_add_tlv(&ocs->iscsi, current_ptr, ISNS_TAG_ISCSI_NODE_TYPE, sizeof(uint32_t), &node_type,
1605  PDU_MEM_SIZE - (msg_ptr - current_ptr) );
1606  if (bytes_added <= 0) {
1607  ocs_log_test(iscsi->os, "Error: Insufficient Space for the PDU Attributes\n");
1608  ocs_free(iscsi->os, msg_ptr, PDU_MEM_SIZE);
1609  return -1;
1610  }
1611  current_ptr += bytes_added;
1612  ocs_isns_log(iscsi->os, "9- iSCSI node type added, current_ptr moved %d bytes\n",
1613  bytes_added);
1614 
1615 
1616  //10- iscsi Alias
1617  bytes_added = ocs_add_tlv(&ocs->iscsi, current_ptr, ISNS_TAG_ISCSI_ALIAS, ocs_strlen(alias), alias,
1618  PDU_MEM_SIZE - (msg_ptr - current_ptr) );
1619  if (bytes_added <= 0) {
1620  ocs_log_test(iscsi->os, "Error: Insufficient Space for the PDU Attributes\n");
1621  ocs_free(iscsi->os, msg_ptr, PDU_MEM_SIZE);
1622  return -1;
1623  }
1624  current_ptr += bytes_added;
1625  ocs_isns_log(iscsi->os, "10- iSCSI name alias added, current_ptr moved %d bytes\n",
1626  bytes_added);
1627 
1628  index++;
1629  iscsi_name = ocs_iscsi_tgt_get_names(ocs, index);
1630  alias = ocs_iscsi_tgt_get_alias(ocs, index);
1631  ocs_print_nl(iscsi, 1);
1632  }
1633  }
1634  /* end of the tgts part */
1635 
1636  /* the initiator part */
1637  if(reg_ini) {
1638  node_type = 0x00000002;
1639  ctr = 0;
1640  iscsi_name = ocs_iscsi_ini_get_name(ocs);
1641  alias = ocs_iscsi_ini_get_alias(ocs);
1642  ocs_print_nl(iscsi, 2);
1643  ocs_isns_log(iscsi->os, "\t\t\tSTART OF ISNS initiator part\n");
1644  ocs_isns_log(iscsi->os, "***iscsi name is (%s) \n", iscsi_name);
1645  ocs_isns_log(iscsi->os, "***its length=%d Bytes\n", (int) ocs_strlen(iscsi_name));
1646  ocs_isns_log(iscsi->os, "***alias is (%s) \n", alias);
1647  ocs_isns_log(iscsi->os, "***its length=%d Bytes\n", (int) ocs_strlen(alias));
1648  ocs_isns_log(iscsi->os, "***Portal TCP Port is (%d) \n", tcp_port);
1649  ocs_isns_log(iscsi->os, "***its length=%d Bytes\n", (int) sizeof(uint32_t));
1650 
1651  ocs_print_nl(iscsi, 1);
1652  ocs_isns_log(iscsi->os, "\t\t\tForming the PDU (adding tlv attrs)\n");
1653  ocs_print_nl(iscsi, 1);
1654 
1655  //6- portal ip address
1656  ocs_isns_log(iscsi->os, "*****Multiple IP Addresses*****\n");
1657  ip_addr_struct = ocs_iscsi_tgt_get_ip_address(ocs, iscsi_name, ctr);
1658  while (ip_addr_struct) {
1659  format_ip_address(ip_addr_struct->ip_type , ip_addr_struct->ip_address,
1660  ip_addr, ARRAY_SIZE(ip_addr) );
1661  ocs_get_ipv6_string(&ocs->iscsi, ip_addr_struct, ipv6_addr);
1662  ocs_isns_log(iscsi->os, "****ip_addr is (%s). its length=%d Bytes \n", ip_addr, (int) ocs_strlen(ip_addr));
1663  bytes_added = ocs_add_tlv(&ocs->iscsi, current_ptr, ISNS_TAG_PORTAL_IP_ADDRESS, sizeof(ipv6_addr), ipv6_addr,
1664  PDU_MEM_SIZE - (msg_ptr - current_ptr) );
1665  if (bytes_added <= 0) {
1666  ocs_log_test(iscsi->os, "Error: Insufficient Space for the PDU Attributes\n");
1667  ocs_free(iscsi->os, msg_ptr, PDU_MEM_SIZE);
1668  return -1;
1669  }
1670  current_ptr += bytes_added;
1671  ocs_isns_log(iscsi->os, "6- portal ip address (%s) added, current_ptr moved %d bytes\n",
1672  ip_addr, bytes_added);
1673 
1674 
1675  //7- portal TCP Port
1676  bytes_added = ocs_add_tlv(&ocs->iscsi, current_ptr, ISNS_TAG_PORTAL_TCP_PORT, sizeof(uint32_t), &tcp_port,
1677  PDU_MEM_SIZE - (msg_ptr - current_ptr) );
1678  if (bytes_added <= 0) {
1679  ocs_log_test(iscsi->os, "Error: Insufficient Space for the PDU Attributes\n");
1680  ocs_free(iscsi->os, msg_ptr, PDU_MEM_SIZE);
1681  return -1;
1682  }
1683  current_ptr += bytes_added;
1684  ocs_isns_log(iscsi->os, "7- portal TCP port added, current_ptr moved %d bytes\n",
1685  bytes_added);
1686 
1687  ctr++;
1688  ip_addr_struct = ocs_iscsi_tgt_get_ip_address(ocs, iscsi_name, ctr);
1689  ocs_print_nl(iscsi, 1);
1690  }
1691 
1692 
1693  //8- iscsi name
1694  bytes_added = ocs_add_tlv(&ocs->iscsi, current_ptr, ISNS_TAG_ISCSI_NAME, ocs_strlen(iscsi_name), iscsi_name,
1695  PDU_MEM_SIZE - (msg_ptr - current_ptr) );
1696  if (bytes_added <= 0) {
1697  ocs_log_test(iscsi->os, "Error: Insufficient Space for the PDU Attributes\n");
1698  ocs_free(iscsi->os, msg_ptr, PDU_MEM_SIZE);
1699  return -1;
1700  }
1701  current_ptr += bytes_added;
1702  ocs_isns_log(iscsi->os, "8- iSCSI name added, current_ptr moved %d bytes\n",
1703  bytes_added);
1704 
1705  //9= iSCSI Node Type
1706  bytes_added = ocs_add_tlv(&ocs->iscsi, current_ptr, ISNS_TAG_ISCSI_NODE_TYPE, sizeof(uint32_t), &node_type,
1707  PDU_MEM_SIZE - (msg_ptr - current_ptr) );
1708  if (bytes_added <= 0) {
1709  ocs_log_test(iscsi->os, "Error: Insufficient Space for the PDU Attributes\n");
1710  ocs_free(iscsi->os, msg_ptr, PDU_MEM_SIZE);
1711  return -1;
1712  }
1713  current_ptr += bytes_added;
1714  ocs_isns_log(iscsi->os, "9- iSCSI node type added, current_ptr moved %d bytes\n",
1715  bytes_added);
1716 
1717 
1718  //10- iscsi Alias
1719  bytes_added = ocs_add_tlv(&ocs->iscsi, current_ptr, ISNS_TAG_ISCSI_ALIAS, ocs_strlen(alias), alias,
1720  PDU_MEM_SIZE - (msg_ptr - current_ptr) );
1721  if (bytes_added <= 0) {
1722  ocs_log_test(iscsi->os, "Error: Insufficient Space for the PDU Attributes\n");
1723  ocs_free(iscsi->os, msg_ptr, PDU_MEM_SIZE);
1724  return -1;
1725  }
1726  current_ptr += bytes_added;
1727  ocs_isns_log(iscsi->os, "10- iSCSI name alias added, current_ptr moved %d bytes\n",
1728  bytes_added);
1729  }
1730  /* end of the initiator part */
1731 
1732  payload_len = current_ptr - msg_ptr - sizeof(isns_hdr_t);
1733  msg_len = payload_len + sizeof(isns_hdr_t);
1734  ocs_print_nl(iscsi, 1);
1735  ocs_isns_log(iscsi->os, "payload_len= %u, msg_len= %u\n", payload_len, msg_len);
1736 
1737  //0- build and add the header of the RegDevMsg
1738  bytes_added = ocs_build_hdr_dev_attr_reg(msg_ptr, (uint16_t) payload_len);
1739  if (bytes_added != 12) {
1740  ocs_log_test(iscsi->os, "ERROR: ISNS error in building the header of the message\n");
1741  ocs_free(iscsi->os, msg_ptr, PDU_MEM_SIZE);
1742  return -2;
1743  }
1744  ocs_isns_log(iscsi->os , "size of header is: %d\n", (int) sizeof(isns_hdr_t) );
1745  ocs_isns_log(iscsi->os, "\t\t\tI WILL SEND NOW!\n");
1746  rc = ocs_iscsi_isns_send(ocs, isns_ip,
1747  3205, //tcp port
1748  msg_ptr,
1749  &msg_len,
1750  PDU_MEM_SIZE);
1751 
1752  if (rc == 0) {
1753  ocs_isns_log(ocs, "iSNS Send Sent, received %d bytes\n", msg_len);
1754  if (msg_len > 0) {
1755  if( ocs_parse_msg_rsp(&ocs->iscsi, __func__, msg_ptr, msg_len, &reg_period, eid) != 0) {
1756  ocs_free(iscsi->os, msg_ptr, PDU_MEM_SIZE);
1757  return -3;
1758  }
1759  }
1760  } else {
1761  ocs_log_test(ocs, "iSNS Send failed with rc %d\n", rc);
1762  ocs_free(iscsi->os, msg_ptr, PDU_MEM_SIZE);
1763  return -4;
1764  }
1765  if(ISNS_ENABLE_ESI == 0) {
1766  cycle_period = (reg_period * 3 / 4) * 1000;
1767  iscsi->isns_ip = *isns_ip;
1768  iscsi->isns_reg_period = cycle_period;
1769 
1770  /* use this defined constant to fix the period for testing */
1771  // cycle_period = ISNS_KEEP_ALIVE_TIMER_PERIOD * 1000;
1772 
1773  ocs_print_nl(iscsi, 3);
1774  ocs_isns_log(ocs, "ESI NOT ENABLED--> will call ocs_isns_keep_alive with cycle_period = %u msec\n", cycle_period);
1775  ocs_setup_timer(ocs, &iscsi->isns_timer,
1777  ocs,
1778  cycle_period, false);
1779  } else {
1780  ocs_isns_log(ocs, "ESI IS ENABLED\n");
1781  }
1782 
1783  ocs_free(iscsi->os, msg_ptr, PDU_MEM_SIZE);
1784  ocs_print_nl(iscsi, 2);
1785  ocs_isns_log(iscsi->os, "\t\t\tEND OF ISNS FUNCTION\n");
1786  ocs_isns_log(iscsi->os, "==============================================================================\n");
1787 
1788  return 0;
1789 }
1790 
1791 
1792 /**
1793  * @ingroup isns
1794  * @brief Sends the DevDereg message to the iSNS server.
1795  *
1796  * This function will de-register all targets in this iSCSI device with
1797  * within the same entity in the isns server.
1798  *
1799  * @param ocs Pointer to the ocs structure that represents this device
1800  * @param isns_ip to the IP addresses of the iSNS server
1801  * @param eid The entity ID assigned by the iSNS server during registration
1802  *
1803  * @return returns zero if successful, negative otherwise
1804  */
1805 int8_t
1806 ocs_isns_deregister(ocs_t *ocs, ocs_ip_address_t *isns_ip, char * eid)
1807 {
1808  void *msg_ptr = NULL;
1809  void *current_ptr = NULL;
1810  char *iscsi_name;
1811  int bytes_added = 0;
1812  uint32_t payload_len = 0;
1813  int32_t rc;
1814  uint32_t msg_len;
1815  uint32_t index = 0;
1816  uint32_t reg_period = 0;
1817  ocs_iscsi_t *iscsi = NULL;
1818 
1819  if (ocs == NULL) {
1820  ocs_log_err(iscsi->os, "iSNS ERROR: ocs is null. Deregistration failed!\n");
1821  return -1;
1822  }
1823 
1824  iscsi = &ocs->iscsi;
1825  ocs_print_nl(&ocs->iscsi, 10);
1826  iscsi_name = ocs_iscsi_tgt_get_names(ocs, index);
1827  ocs_isns_log(ocs, "ISNS deregister begin\n");
1828 
1829  ocs_print_nl(&ocs->iscsi, 2);
1830  if (isns_ip == NULL) {
1831  ocs_log_err(iscsi->os, "iSNS ERROR: isns_ip is null. Deregistration failed!\n");
1832  return -1;
1833  }
1834 
1835  msg_ptr = ocs_malloc(ocs, PDU_MEM_SIZE, OCS_M_ZERO | OCS_M_NOWAIT);
1836  if (msg_ptr == NULL) {
1837  ocs_log_err(iscsi->os, "iSNS ERROR: Failed to allocate memory for msg_ptr\n");
1838  return -1;
1839  }
1840  current_ptr = msg_ptr + sizeof(isns_hdr_t);
1841 
1842  ocs_isns_log(iscsi->os, "\t\t\tSTART OF ISNS tgts part\n");
1843  ocs_print_nl(&ocs->iscsi, 2);
1844  ocs_isns_log(iscsi->os, "\t\t\tForming the PDU (adding tlv attrs)\n");
1845  ocs_print_nl(&ocs->iscsi, 2);
1846  //1-src attr =iscsi name
1847  bytes_added = ocs_add_tlv(&ocs->iscsi, current_ptr, ISNS_TAG_ISCSI_NAME, ocs_strlen(iscsi_name),
1848  iscsi_name, PDU_MEM_SIZE - (msg_ptr - current_ptr) );
1849  if (bytes_added <= 0) {
1850  ocs_log_test(iscsi->os, "Error: Insufficient Space for the PDU Attributes\n");
1851  ocs_free(iscsi->os, msg_ptr, PDU_MEM_SIZE);
1852  return -1;
1853  }
1854  current_ptr += bytes_added;
1855  ocs_isns_log(ocs, "iscsi_name = (%s) size = %d\n", iscsi_name, (int) ocs_strlen(iscsi_name));
1856  ocs_isns_log(iscsi->os, " - iSCSI name added, current_ptr moved %d bytes\n",
1857  bytes_added);
1858 
1859  //2- delimiter
1860  bytes_added = ocs_add_delimiter(current_ptr, PDU_MEM_SIZE - (msg_ptr - current_ptr) );
1861  if (bytes_added <= 0) {
1862  ocs_log_test(iscsi->os, "Error: Insufficient Space for the PDU Attributes\n");
1863  ocs_free(iscsi->os, msg_ptr, PDU_MEM_SIZE);
1864  return -1;
1865  }
1866  current_ptr += bytes_added;
1867  ocs_isns_log(iscsi->os, " - delimiter added, current_ptr moved %d bytes\n",
1868  bytes_added);
1869 
1870 
1871  // EID
1872  bytes_added = ocs_add_tlv(&ocs->iscsi, current_ptr, ISNS_TAG_ENTITY_IDENTIFIER, ocs_strlen(eid), eid,
1873  PDU_MEM_SIZE - (msg_ptr - current_ptr) );
1874  if (bytes_added <= 0) {
1875  ocs_log_test(iscsi->os, "Error: Insufficient Space for the PDU Attributes\n");
1876  ocs_free(iscsi->os, msg_ptr, PDU_MEM_SIZE);
1877  return -1;
1878  }
1879  current_ptr += bytes_added;
1880  ocs_isns_log(ocs, "eid = (%s) size = %d\n", eid, (int) ocs_strlen(eid));
1881  ocs_isns_log(iscsi->os, " - EID, current_ptr moved %d bytes\n",
1882  bytes_added);
1883 
1884 
1885  payload_len = current_ptr - msg_ptr - sizeof(isns_hdr_t);
1886  msg_len = payload_len + sizeof(isns_hdr_t);
1887  ocs_print_nl(iscsi, 1);
1888  ocs_isns_log(iscsi->os, "payload_len= %u, msg_len= %u\n", payload_len, msg_len);
1889 
1890  //0- build and add the header of the RegDevMsg
1891  bytes_added = ocs_build_hdr_dev_dereg(msg_ptr, (uint16_t) payload_len);
1892  if (bytes_added != 12) {
1893  ocs_log_test(iscsi->os, "ERROR: ISNS error in building the header of the message\n");
1894  ocs_free(iscsi->os, msg_ptr, PDU_MEM_SIZE);
1895  return -2;
1896  }
1897  ocs_isns_log(iscsi->os , "size of header is: %d\n", (int) sizeof(isns_hdr_t) );
1898 
1899  ocs_isns_log(iscsi->os, "\t\t\tI WILL SEND NOW!\n");
1900  rc = ocs_iscsi_isns_send(ocs, isns_ip,
1901  3205, //tcp port
1902  msg_ptr,
1903  &msg_len,
1904  PDU_MEM_SIZE);
1905 
1906  if (rc == 0) {
1907  ocs_isns_log(ocs, "iSNS Send Sent, received %d bytes\n", msg_len);
1908  if (msg_len > 0) {
1909  if( ocs_parse_msg_rsp(&ocs->iscsi, __func__, msg_ptr, msg_len, &reg_period, eid) != 0) {
1910  ocs_free(iscsi->os, msg_ptr, PDU_MEM_SIZE);
1911  return -3;
1912  }
1913  }
1914  } else {
1915  ocs_log_test(ocs, "iSNS Send failed with rc %d\n", rc);
1916  ocs_free(iscsi->os, msg_ptr, PDU_MEM_SIZE);
1917  return -4;
1918  }
1919  ocs_free(iscsi->os, msg_ptr, PDU_MEM_SIZE);
1920  ocs_print_nl(iscsi, 2);
1921  ocs_isns_log(iscsi->os, "\t\t\tEND OF ISNS FUNCTION\n");
1922  ocs_isns_log(iscsi->os, "==============================================================================\n");
1923 
1924  return 0;
1925 }
void ocs_str_to_ip_struct(ocs_iscsi_t *iscsi, char *ip, ocs_ip_address_t *ip_struct)
Converts a string ip into an ip struct.
Definition: ocs_isns.c:256
#define ISNS_ERROR_DOMAIN_ID_UNAVAILABLE
Definition: ocs_isns.h:114
ocs_ip_address_t * ocs_iscsi_tgt_get_ip_address(ocs_t *ocs, char *tgt_name, uint32_t index)
Returns the IP address of the target name based on the index.
#define ISNS_ERROR_NO_SUCH_ENTRY
Definition: ocs_isns.h:104
#define ISNS_TAG_ENTITY_PROTOCOL
Definition: ocs_isns.h:78
#define ISNS_FLAG_LAST
Definition: ocs_isns.h:63
static void * ocs_parse_qry_rsp(ocs_iscsi_t *iscsi, void *rsp_ptr, uint16_t rsp_len, uint16_t *ret_nodes_count)
Parses the response of the DevAttrQry message.
Definition: ocs_isns.c:763
#define ISCSI_PROTOCOL
Definition: ocs_isns.h:46
#define ISNS_ERROR_OPTION_NOT_UNDERSTOOD
Definition: ocs_isns.h:108
static int ocs_add_delimiter(void *curr, int remaining)
Create a delimiter attribute.
Definition: ocs_isns.c:552
uint16_t payload_length
Definition: ocs_isns.h:125
int8_t ocs_isns_register(ocs_iscsi_t *iscsi, uint8_t reg_tgts, uint8_t reg_ini, ocs_ip_address_t *isns_ip, char *eid)
Sends the DevAttrReg message to the iSNS server.
Definition: ocs_isns.c:1420
#define ISNS_FUNC_DEV_ATTR_REG
Definition: ocs_isns.h:58
#define ISNS_ERROR_INVALID_UPDATE
Definition: ocs_isns.h:109
static int ocs_build_hdr_dev_dereg(void *curr, uint16_t len)
Builds the header of the DevAttrDereg message.
Definition: ocs_isns.c:506
char * ocs_get_iscsi_name(ocs_iscsi_t *iscsi, void *p, uint16_t index)
Gets the iscsi name of a given node.
Definition: ocs_isns.c:223
#define ISNS_FUNC_DEV_ATTR_DEREG
Definition: ocs_isns.h:60
#define ISNS_ERROR_INVALID_REG
Definition: ocs_isns.h:98
static int8_t ocs_create_nodes(ocs_iscsi_t *iscsi, void *rsp_ptr, int16_t bytes_left, void *ret)
Creates an isns node.
Definition: ocs_isns.c:351
static void ocs_isns_keep_alive(void *arg)
Sends a query to an ISNS target to keep it alive.
Definition: ocs_isns.c:1385
#define ISNS_VERSION
Definition: ocs_isns.h:50
#define ISNS_FLAG_REPLACE
Definition: ocs_isns.h:64
#define ISNS_TAG_ESI_PORT
Definition: ocs_isns.h:88
#define ISNS_TAG_ENTITY_IDENTIFIER
Definition: ocs_isns.h:77
#define ISNS_ERROR_BUSY
Definition: ocs_isns.h:107
#define ISNS_FUNC_DEV_ATTR_QRY
Definition: ocs_isns.h:59
char * ocs_iscsi_ini_get_name(ocs_t *ocs)
Return this initiator&#39;s name.
static void ocs_parse_flags(ocs_iscsi_t *iscsi, uint16_t flags)
Parses the flags of the response of an isns message.
Definition: ocs_isns.c:672
#define ISNS_TAG_REG_PERIOD
Definition: ocs_isns.h:82
#define ISNS_FLAG_CLIENT
Definition: ocs_isns.h:67
uint16_t function_id
Definition: ocs_isns.h:124
#define ISNS_ERROR_FUNC_ID
Definition: ocs_isns.h:110
#define ISNS_TAG_ESI_INTERVAL
Definition: ocs_isns.h:87
#define ISNS_ESI_PORT
Definition: ocs_isns.h:47
char * ocs_iscsi_tgt_get_names(ocs_t *ocs, uint32_t index)
Returns the target name based on the index.
ocs_ip_type_e ip_type
Definition: ocs_iscsi_api.h:75
#define ocs_isns_log(os, fmt,...)
Definition: ocs_isns.h:166
static void * ocs_isns_qry_attr(ocs_iscsi_t *iscsi, ocs_ip_address_t *isns_ip)
Sends the DevAttrReg message to the iSNS server.
Definition: ocs_isns.c:1236
uint32_t isns_reg_period
Definition: ocs_iscsi.h:346
uint16_t transaction_id
Definition: ocs_isns.h:127
static int ocs_build_hdr_dev_attr_qry(void *curr, uint16_t len)
Builds the header of the DevAttrQry message.
Definition: ocs_isns.c:528
#define ISNS_ERROR_UNALLCATED_DOMAIN_ID
Definition: ocs_isns.h:115
#define ISNS_TAG_PORTAL_INDEX
Definition: ocs_isns.h:89
#define ISNS_TAG_ISCSI_NODE_TYPE
Definition: ocs_isns.h:92
static int8_t ocs_create_node(ocs_iscsi_t *iscsi, void *ptr, uint16_t num)
Creates an empty isns node.
Definition: ocs_isns.c:196
#define ISNS_ERROR_INTERNAL_ERROR
Definition: ocs_isns.h:106
#define ISNS_TAG_ISCSI_ALIAS
Definition: ocs_isns.h:93
#define ISNS_TRANSACTION_ID_2
Definition: ocs_isns.h:53
uint8_t ip_address[16]
Definition: ocs_iscsi_api.h:76
#define ISNS_ENABLE_ESI
Definition: ocs_isns.h:70
#define ISNS_TAG_PORTAL_IP_ADDRESS
Definition: ocs_isns.h:85
static void ocs_fill_nodes_values(ocs_iscsi_t *iscsi, void *rsp_ptr, int16_t bytes_left, void *ret)
Fills the attributes of the isns node.
Definition: ocs_isns.c:420
iSCSI object
Definition: ocs_iscsi.h:293
ocs_isns_ip_port_t * ipp
Definition: ocs_isns.h:143
#define ISNS_ERROR_SOURCE_UNATHORIZED
Definition: ocs_isns.h:103
ocs_os_handle_t os
Definition: ocs_iscsi.h:294
#define ISNS_ERROR_SCN_REG_REJ
Definition: ocs_isns.h:112
#define ISNS_ERROR_MSG_FORMAT
Definition: ocs_isns.h:97
#define ISNS_ERROR_NOT_IMPL
Definition: ocs_isns.h:113
static int ocs_binary_attr(int tag)
Determines whether a given isns attribute is a numeric (binary) one.
Definition: ocs_isns.c:88
#define ISNS_TRANSACTION_ID_1
Definition: ocs_isns.h:52
#define ISNS_TAG_PORTAL_TCP_PORT
Definition: ocs_isns.h:86
#define ISNS_TAG_ISCSI_NAME
Definition: ocs_isns.h:91
#define ISNS_ERROR_SCN_EVENT_REJ
Definition: ocs_isns.h:111
#define ISNS_TAG_DELIMITER
Definition: ocs_isns.h:76
void * ocs_isns_qry_tgts(ocs_iscsi_t *iscsi, ocs_ip_address_t *isns_ip, uint16_t *ret_nodes_count)
Sends the DevAttrReg message to the iSNS server.
Definition: ocs_isns.c:925
static int ocs_build_hdr_dev_attr_reg(void *curr, uint16_t len)
Builds the header of the DevAttrReg message.
Definition: ocs_isns.c:483
#define ISNS_ERROR_INVALID_DEREG
Definition: ocs_isns.h:117
uint16_t ocs_get_iscsi_ipp_count(ocs_iscsi_t *iscsi, void *p, uint16_t index)
Gets the count of the ip_port structs in a given node.
Definition: ocs_isns.c:240
uint16_t flags
Definition: ocs_isns.h:126
uint16_t iSNSP_version
Definition: ocs_isns.h:123
int32_t ocs_isns_initialize(ocs_iscsi_t *iscsi)
Initialize the iSNS module.
Definition: ocs_isns.c:58
void format_ip_address(ocs_ip_type_e ip_type, uint8_t *address, char *buffer, int size)
Format an IP address into a string.
Definition: ocs_iscsi.c:460
char * ocs_get_ip(ocs_iscsi_t *iscsi, void *p, uint16_t index, uint16_t ip_index)
Gets the ip address of a given isns node.
Definition: ocs_isns.c:301
char * ocs_iscsi_ini_get_alias(ocs_t *ocs)
Returns the initiator alias.
#define ISNS_ERROR_INVALID_QUERY
Definition: ocs_isns.h:100
#define ISNS_ERROR_SOURCE_ABSENT
Definition: ocs_isns.h:102
uint16_t ocs_get_port(ocs_iscsi_t *iscsi, void *p, uint16_t index, uint16_t ip_index)
Gets the port of a given isns node.
Definition: ocs_isns.c:325
ocs_ip_type_e
enum identifying the types of IP addresses.
Definition: ocs_iscsi_api.h:46
#define ISNS_ERROR_SOURCE_UNKNOWN
Definition: ocs_isns.h:101
static void ocs_parse_rsp_hdr(ocs_iscsi_t *iscsi, void *rsp)
Parses the header of the response of an isns message.
Definition: ocs_isns.c:717
#define ISNS_ERROR_REG_FEATURE_UNSUPPORTED
Definition: ocs_isns.h:118
#define ISNS_ERROR_UNKNOWN
Definition: ocs_isns.h:96
#define ISNS_ERROR_VERSION_NOT_SUPPORTED
Definition: ocs_isns.h:105
#define ISNS_ESI_INTERVAL
Definition: ocs_isns.h:48
int32_t ocs_iscsi_isns_send(ocs_t *ocs, ocs_ip_address_t *isns_server, uint32_t tcp_port, void *buffer, uint32_t *pkt_len, uint32_t buff_len)
Sends an iSNS packet to a server to test the interface.
Definition: ocs_iscsi.c:1196
#define ISNS_ERROR_RESERVED
Definition: ocs_isns.h:99
int32_t ocs_isns_teardown(ocs_iscsi_t *iscsi)
Shutdown the iSNS module.
Definition: ocs_isns.c:74
#define ISNS_STARTING_SEQ_ID
Definition: ocs_isns.h:55
static int8_t ocs_parse_msg_rsp(ocs_iscsi_t *iscsi, const char *original_func_name, void *rsp_ptr, uint16_t rsp_len, uint32_t *reg_period, char *eid)
Parses the response of an isns message.
Definition: ocs_isns.c:1102
uint16_t sequence_id
Definition: ocs_isns.h:128
#define PDU_MEM_SIZE
Definition: ocs_isns.h:45
static char * ocs_get_tag_name(uint32_t tag)
Gets the name of the given isns tag.
Definition: ocs_isns.c:126
#define OCS_ISCSI_TCP_PORT
int32_t ocs_iscsi_inet_pton6(const char *src, ocs_ip_address_t *ip)
Converts an IPv6 address from a string to the IP structure.
Definition: ocs_iscsi.c:574
static char * ocs_get_error_name(uint32_t error_number)
Gets the name of the given isns error.
Definition: ocs_isns.c:153
structure wrapping an IP address together with it&#39;s type.
Definition: ocs_iscsi_api.h:74
ocs_ip_address_t isns_ip
Definition: ocs_iscsi.h:345
static int ocs_add_tlv(ocs_iscsi_t *iscsi, void *curr, uint32_t tag, uint32_t len, void *value, int remaining)
Create a tag-length-value attribute.
Definition: ocs_isns.c:576
char * ocs_iscsi_tgt_get_alias(ocs_t *ocs, uint32_t index)
Returns the target alias based on the index.
int8_t ocs_isns_deregister(ocs_t *ocs, ocs_ip_address_t *isns_ip, char *eid)
Sends the DevDereg message to the iSNS server.
Definition: ocs_isns.c:1806
#define ISNS_ERROR_ESI_UNAVAILABLE
Definition: ocs_isns.h:116
char iname[256]
Definition: ocs_isns.h:141
static void ocs_get_ipv6_string(ocs_iscsi_t *iscsi, ocs_ip_address_t *addr, uint8_t *ret_addr)
Forms an v6-format ip string.
Definition: ocs_isns.c:646
ocs_timer_t isns_timer
Definition: ocs_iscsi.h:344
#define ISNS_FLAG_FIRST
Definition: ocs_isns.h:62
static void ocs_print_nl(ocs_iscsi_t *iscsi, uint32_t ctr)
Prints a number of empty lines.
Definition: ocs_isns.c:110
uint16_t ipp_count
Definition: ocs_isns.h:142