Пример #1
0
int main(int argc, char *argv[]){
  char conf_file[128];
  
  int status = 0;
  int wpid = 0;
  
  if(argc <= 1){
	strcpy(conf_file, "targets.txt");
  }else{
	printf("%s, %s\n", argv[0], argv[1]);
	strcpy(conf_file, argv[1]);
  }
  add_targets(conf_file);
  attach();
  
  while(1)
	sleep(1);

  return 0;

}
Пример #2
0
Файл: util.c Проект: imp/slist
/*
 * []----
 * | parse_text -- receive text information from initiator and parse
 * |
 * | Read in the current data based on the amount which the login PDU says
 * | should be available. Add it to the end of previous data if it exists.
 * | Previous data would be from a PDU which had the 'C' bit set and was
 * | stored in the connection.
 * |
 * | Once values for parameter name has been selected store outgoing string
 * | in text message for response.
 * |
 * | If errcode is non-NULL the appropriate login error code will be
 * | stored.
 * []----
 */
Boolean_t
parse_text(iscsi_conn_t *c, int dlen, char **text, int *text_length,
    int *errcode)
{
	char		*p		= NULL;
	char		*n;
	char		*cur_pair;
	char		param_rsp[32];
	int		plen;		/* pair length */
	Boolean_t	rval		= True;
	char		*target_name    = NULL;
	char		*initiator_name = NULL;
	char		param_buf[16];

	if ((p = (char *)malloc(dlen)) == NULL)
		return (False);

	/*
	 * Read in data to buffer.
	 */
	if (read(c->c_fd, p, dlen) != dlen) {
		free(p);
		return (False);
	}

	queue_prt(c->c_mgmtq, Q_CONN_NONIO, "CON%x  Available text size %d\n",
	    c->c_num, dlen);

	/*
	 * Read in and toss any pad data
	 */
	if (dlen % ISCSI_PAD_WORD_LEN) {
		char junk[ISCSI_PAD_WORD_LEN];
		int pad_len = ISCSI_PAD_WORD_LEN - (dlen % ISCSI_PAD_WORD_LEN);

		if (read(c->c_fd, junk, pad_len) != pad_len) {
			free(p);
			return (False);
		}
	}

	if (c->c_text_area != NULL) {
		if ((n = (char *)realloc(c->c_text_area,
		    c->c_text_len + dlen)) == NULL) {
			free(p);
			return (False);
		}
		bcopy(p, n + c->c_text_len, dlen);

		/*
		 * No longer need the space allocated to 'p' since it
		 * will point to the aggregated area of all data.
		 */
		free(p);

		/*
		 * Point 'p' to this new area for parsing and save the
		 * combined length in dlen.
		 */
		p = n;
		dlen += c->c_text_len;

		/*
		 * Clear the indication that space has been allocated
		 */
		c->c_text_area = NULL;
		c->c_text_len = 0;
	}

	/*
	 * At this point 'p' points to the name/value parameters. Need
	 * to cycle through each pair.
	 */
	n = p;
	while (dlen > 0) {
		cur_pair = n;

		plen = strlen(n);
		if ((n = strchr(cur_pair, ISCSI_TEXT_SEPARATOR)) == NULL) {
			if (errcode != NULL)
				*errcode =
				    (ISCSI_STATUS_CLASS_INITIATOR_ERR << 8) |
				    ISCSI_LOGIN_STATUS_INIT_ERR;
			rval = False;
			break;
		} else
			*n++ = '\0';

		queue_prt(c->c_mgmtq, Q_CONN_LOGIN, "CON%x    %-24s = %s\n",
		    c->c_num, cur_pair, n);

		/*
		 * At this point, 'cur_pair' points at the name and 'n'
		 * points at the value.
		 */

		/*
		 * []--------------------------------------------------[]
		 * | The order of parameters processed matches the	|
		 * | the RFC in section 12.				|
		 * []--------------------------------------------------[]
		 */
		/*
		 * 12.1 -- HeaderDigest
		 * Negotiated
		 */
		if (strcmp("HeaderDigest", cur_pair) == 0) {

			rval = parse_digest_vals(&c->c_header_digest,
			    cur_pair, n, text, text_length);

		/*
		 * 12.1 -- DataDigest
		 * Negotiated
		 */
		} else if (strcmp("DataDigest", cur_pair) == 0) {

			rval = parse_digest_vals(&c->c_data_digest, cur_pair,
			    n, text, text_length);

		/*
		 * 12.2 -- MaxConnections
		 * Negotiated
		 */
		} else if (strcmp("MaxConnections", cur_pair) == 0) {

			/* ---- To be fixed ---- */
			c->c_max_connections = 1;
			(void) snprintf(param_rsp, sizeof (param_rsp),
			    "%d", c->c_max_connections);
			rval = add_text(text, text_length,
			    cur_pair, param_rsp);

		/*
		 * 12.3 -- SendTargets
		 * Declarative
		 */
		} else if (strcmp("SendTargets", cur_pair) == 0) {

			if ((c->c_sess->s_type != SessionDiscovery) &&
			    (strcmp("All", n) == 0)) {
				rval = add_text(text, text_length, cur_pair,
				    "Irrelevant");
			} else {
				rval = add_targets(c, text, text_length);
			}

		/*
		 * 12.4 -- TargetName
		 * Declarative
		 */
		} else if (strcmp("TargetName", cur_pair) == 0) {

			send_named_msg(c, msg_target_name, n);
			target_name = n;

		/*
		 * 12.5 -- IntiatorName
		 * Declarative
		 */
		} else if (strcmp("InitiatorName", cur_pair) == 0) {

			send_named_msg(c, msg_initiator_name, n);
			initiator_name = n;

		/* ---- Section 12.6 is handled within TargetName ---- */

		/*
		 * 12.7 -- InitiatorAlias
		 * Declarative
		 */
		} else if (strcmp("InitiatorAlias", cur_pair) == 0) {

			send_named_msg(c, msg_initiator_alias, n);

		/*
		 * Sections 12.8 (TargetAddress) and 12.9
		 * (TargetPortalGroupTag) are handled during the SendTargets
		 * processing.
		 */

		/*
		 * 12.10 -- IntialR2T
		 * Negotiated
		 */
		} else if (strcmp("InitialR2T", cur_pair) == 0) {

			c->c_initialR2T = True;
			rval = add_text(text, text_length, cur_pair, "Yes");

		/*
		 * 12.11 -- ImmediateData
		 * Negotiated
		 */
		} else if (strcmp("ImmediateData", cur_pair) == 0) {

			/*
			 * Since we can handle immediate data without
			 * a problem just echo back what the initiator
			 * sends. If the initiator decides to violate
			 * the spec by sending immediate data even though
			 * they've disabled it, it's their problem and
			 * we'll deal with the data.
			 */
			c->c_immediate_data = strcmp(n, "No") ? True : False;
			rval = add_text(text, text_length, cur_pair, n);

		/*
		 * 12.12 -- MaxRecvDataSegmentLength
		 * Declarative
		 */
		} else if (strcmp("MaxRecvDataSegmentLength", cur_pair) == 0) {

			c->c_max_recv_data = strtol(n, NULL, 0);
			rval = add_text(text, text_length, cur_pair, n);

		/*
		 * 12.13 -- MaxBurstLength
		 * Negotiated
		 */
		} else if (strcmp("MaxBurstLength", cur_pair) == 0) {

			c->c_max_burst_len = strtol(n, NULL, 0);
			rval = add_text(text, text_length, cur_pair, n);

		/*
		 * 12.14 -- FirstBurstLength
		 * Negotiated
		 */
		} else if (strcmp("FirstBurstLength", cur_pair) == 0) {

			/*
			 * We can handle anything the initiator wishes
			 * to shove in our direction. So, store the value
			 * in case we ever wish to validate input data,
			 * but there's no real need to do so.
			 */
			c->c_first_burst_len = strtol(n, NULL, 0);
			rval = add_text(text, text_length, cur_pair, n);

		/*
		 * 12.15 DefaultTime2Wait
		 * Negotiated
		 */
		} else if (strcmp("DefaultTime2Wait", cur_pair) == 0) {

			c->c_default_time_2_wait = strtol(n, NULL, 0);
			rval = add_text(text, text_length, cur_pair, n);

		/*
		 * 12.16 -- DefaultTime2Retain
		 * Negotiated
		 */
		} else if (strcmp("DefaultTime2Retain", cur_pair) == 0) {

			c->c_default_time_2_retain = strtol(n, NULL, 0);
			rval = add_text(text, text_length, cur_pair, n);

		/*
		 * 12.17 -- MaxOutstandingR2T
		 * Negotiated
		 */
		} else if (strcmp("MaxOutstandingR2T", cur_pair) == 0) {

			/*
			 * Save the value, but at most we'll toss out
			 * one R2T packet.
			 */
			c->c_max_outstanding_r2t = strtol(n, NULL, 0);
			rval = add_text(text, text_length, cur_pair, n);

		/*
		 * 12.18 -- DataPDUInOder
		 * Negotiated
		 */
		} else if (strcmp("DataPDUInOrder", cur_pair) == 0) {

			/*
			 * We can handle DataPDU's out of order and
			 * currently we'll only send them in order. We're
			 * to far removed from the hardware to see data
			 * coming off of the platters out of order so
			 * it's unlikely we'd ever implement this feature.
			 * Store the parameter and echo back the initiators
			 * request.
			 */
			c->c_data_pdu_in_order = strcmp(n, "Yes") == 0 ?
			    True : False;
			rval = add_text(text, text_length, cur_pair, n);

		/*
		 * 12.19 -- DataSequenceInOrder
		 * Negotiated
		 */
		} else if (strcmp("DataSequenceInOrder", cur_pair) == 0) {

			/*
			 * Currently we're set up to look at and require
			 * PDU sequence numbers be in order. The check
			 * now is only done as a prelude to supporting
			 * MC/S and guaranteeing the order of incoming
			 * packets on different connections.
			 */
			c->c_data_sequence_in_order = True;
			rval = add_text(text, text_length, cur_pair, "Yes");

		/*
		 * 12.20 -- ErrorRecoveryLevel
		 * Negotiated
		 */
		} else if (strcmp("ErrorRecoveryLevel", cur_pair) == 0) {

			c->c_erl = 0;
			(void) snprintf(param_rsp, sizeof (param_rsp),
			    "%d", c->c_erl);
			rval = add_text(text, text_length,
			    cur_pair, param_rsp);

		/*
		 * 12.21 -- SessionType
		 * Declarative
		 */
		} else if (strcmp("SessionType", cur_pair) == 0) {

			c->c_sess->s_type = strcmp(n, "Discovery") == 0 ?
			    SessionDiscovery : SessionNormal;


		/*
		 * Appendix A 3.1 -- IFMarker
		 * Negotiated
		 */
		} else if (strcmp("IFMarker", cur_pair) == 0) {

			c->c_ifmarker = False;
			rval = add_text(text, text_length, cur_pair, "No");

		/*
		 * Appendix A 3.1 -- OFMarker
		 * Negotiated
		 */
		} else if (strcmp("OFMarker", cur_pair) == 0) {

			c->c_ofmarker = False;
			rval = add_text(text, text_length, cur_pair, "No");

		} else if ((strcmp("AuthMethod", cur_pair) == 0) ||
		    (strcmp("CHAP_A", cur_pair) == 0) ||
		    (strcmp("CHAP_I", cur_pair) == 0) ||
		    (strcmp("CHAP_C", cur_pair) == 0) ||
		    (strcmp("CHAP_N", cur_pair) == 0) ||
		    (strcmp("CHAP_R", cur_pair) == 0)) {

			rval = add_text(&(c->auth_text), &c->auth_text_length,
			    cur_pair, n);

		} else {

			/*
			 * It's perfectly legitimate for an initiator to
			 * send us a parameter we don't currently understand.
			 * For example, an initiator that supports iSER will
			 * send an RDMA options parameter. If we respond with
			 * a valid return value it knows to switch to iSER
			 * for future processing.
			 */
			rval = add_text(text, text_length,
			    cur_pair, "NotUnderstood");

			/*
			 * Go ahead a log this information in case we see
			 * something unexpected.
			 */
			queue_prt(c->c_mgmtq, Q_CONN_ERRS,
			    "CON%x  Unknown parameter %s=%s\n",
			    c->c_num, cur_pair, n);
		}

		/*
		 * If parsed both Initiator and Target names have been parsed,
		 * then it is now time to load the connection parameters.
		 *
		 * This may fail because the target doesn't exist or the
		 * initiator doesn't have permission to access this target.
		 */
		if ((target_name != NULL) && (initiator_name != NULL)) {
			if ((rval = connection_parameters_get(c, target_name))
			    == False) {
				if ((errcode != NULL) && (*errcode == 0))
					*errcode =
					    (ISCSI_STATUS_CLASS_INITIATOR_ERR
					    << 8) |
					    ISCSI_LOGIN_STATUS_TGT_FORBIDDEN;
			} else if ((rval = add_text(text, text_length,
			    "TargetAlias", c->c_targ_alias)) == True) {

				/*
				 * Add TPGT now
				 */
				(void) snprintf(param_buf, sizeof (param_buf),
				    "%d", c->c_tpgt);
				rval = add_text(text, text_length,
				    "TargetPortalGroupTag", param_buf);
				target_name = initiator_name = NULL;
			}
		}

		if (rval == False) {
			/*
			 * Make sure the caller wants error status and that it
			 * hasn't already been set.
			 */
			if ((errcode != NULL) && (*errcode == 0))
				*errcode =
				    (ISCSI_STATUS_CLASS_TARGET_ERR << 8) |
				    ISCSI_LOGIN_STATUS_TARGET_ERROR;
			break;
		}

		/*
		 * next pair of parameters. 1 is added to include the NULL
		 * byte and the end of each string.
		 */
		n = cur_pair + plen + 1;
		dlen -= (plen + 1);
	}

	if (p != NULL)
		free(p);

	return (rval);
}