/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <poll.h>
#include <errno.h>
#include "isns_server.h"
#include "isns_log.h"
#include "isns_pdu.h"
/* externs */
#ifdef DEBUG
extern void dump_pdu2(isns_pdu_t *);
#endif
/*
* local functions.
*/
int fd,
isns_pdu_t **pdu,
int rcv_timeout
)
{
int poll_cnt;
/* initialize to zero */
*pdu_size = 0;
/* Receive the header first */
if (tmp_pdu_hdr == NULL) {
return (0);
}
/* Initialization of the message header. */
/* msg.msg_flags = MSG_WAITALL, */
/* Poll and receive the pdu header */
poll_cnt = 0;
do {
if (err <= 0) {
poll_cnt ++;
} else {
break;
}
} while (poll_cnt < ISNS_RCV_RETRY_MAX);
if (poll_cnt >= ISNS_RCV_RETRY_MAX) {
return (0);
}
if (bytes_received <= 0) {
return (0);
}
/* Verify the received payload len is within limit */
if (payload_len > ISNSP_MAX_PAYLOAD_SIZE) {
return (0);
}
/* Proceed to receive additional data. */
if (tmp_pdu_data == NULL) {
return (0);
}
/* Initialization of the message header. */
/* msg.msg_flags = MSG_WAITALL, */
/* poll and receive the pdu payload */
poll_cnt = 0;
do {
if (err <= 0) {
poll_cnt ++;
} else {
break;
}
} while (poll_cnt < ISNS_RCV_RETRY_MAX);
if (poll_cnt >= ISNS_RCV_RETRY_MAX) {
return (0);
}
if (bytes_received <= 0) {
return (0);
}
*pdu_size = 0;
return (0);
}
tmp_pdu_data = NULL;
tmp_pdu_hdr = NULL;
return (total_bytes_received);
}
int
int fd,
)
{
/* Initialization of the message header. */
/* msg.msg_flags = MSG_WAITALL, */
/*
* Initialize the pdu flags.
*/
/*
* Initialize the pdu sequence id.
*/
seq = 0;
#ifdef DEBUG
#endif
do {
/* set the payload for sending */
if (pl > ISNSP_MAX_PAYLOAD_SIZE) {
} else {
/* set the last pdu flag */
}
/* set the pdu flags */
/* set the pdu sequence id */
/* send the packet */
/* get rid of the first pdu flag */
flags &= ~(ISNS_FLAG_FIRST_PDU);
/* next part of payload */
/* add the length of header for verification */
/* increase the sequence id by one */
seq ++;
if (bytes_sent == send_len) {
return (0);
} else {
return (-1);
}
}
static int
isns_pdu_t **rsp,
)
{
int ec = 0;
*sz = RSP_PDU_FRAG_SZ;
} else {
}
}
return (ec);
}
int
isns_pdu_t **rsp,
)
{
if (ec == 0) {
/* leave space for status code */
*pl = 4;
}
return (ec);
}
int
isns_pdu_t **pdu,
)
{
if (ec == 0) {
*pl = 0;
}
return (ec);
}
int
isns_pdu_t **pdu,
)
{
}
int
int code
)
{
/* reset the payload length */
*pl = 4;
}
return (0);
}
int
isns_pdu_t **pdu,
void *attr_data,
int pflag
)
{
int ec = 0;
/* The attribute length must be 4-byte aligned. Section 5.1.3. */
/* Check if we are going to exceed the maximum PDU length. */
} else {
return (ec);
}
}
switch (attr_id) {
case ISNS_DELIMITER_ATTR_ID:
break;
/* IPv6 */
sizeof (in6_addr_t));
break;
case ISNS_EID_ATTR_ID:
case ISNS_ISCSI_NAME_ATTR_ID:
case ISNS_ISCSI_ALIAS_ATTR_ID:
attr_len);
break;
default:
if (attr_len == 8) {
if (pflag == 0) {
/*
* In the iSNS protocol, there is only one
* attribute ISNS_TIMESTAMP_ATTR_ID which has
* 8 bytes length integer value and when the
* function "pdu_add_tlv" is called for adding
* the timestamp attribute, the value of
* the attribute is always passed in as its
* address, i.e. the pflag sets to 1.
* So it is an error when we get to this code
* path.
*/
return (ec);
} else {
}
} else if (attr_len == 4) {
if (pflag == 0) {
} else {
}
}
break;
}
/*
* Convert the network byte ordered payload length to host byte
* ordered for local address calculation.
*/
*pl += attr_tlv_len;
/*
* The payload length might exceed the maximum length of a
* payload that isnsp allows, we will split the payload and
* set the size of each payload before they are sent.
*/
return (ec);
}
)
{
/* response code */
if (payload_len < 4) {
return (NULL);
}
payload += 4;
payload_len -= 4;
}
if (payload_len > 8) {
}
return (tlv);
}
)
{
/* reset */
*key_len = 0;
/* response code */
if (payload_len <= 4) {
return (NULL);
}
payload += 4;
payload_len -= 4;
}
/* skip the soure */
if (payload_len >= 8) {
while (payload_len >= 8) {
break;
}
}
}
if (*key_len >= 8) {
return (key);
}
return (NULL);
}
)
{
int found_op = 0;
/* reset */
*op_len = 0;
/* response code */
if (payload_len < 4) {
return (NULL);
}
payload += 4;
payload_len -= 4;
}
/* tlvs */
while (payload_len >= 8) {
if (found_op != 0) {
} else {
/* found it */
*op_len = payload_len;
found_op = 1;
}
}
}
if (*op_len >= 8) {
return (op);
}
return (NULL);
}