⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 isns.c

📁 iscsi企业级target.很好用
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Implementation for iSCSI iSNS support. * (C) 2004 Ming Zhang <mingz@ele.uri.edu> * This code is licenced under the GPL. */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <errno.h>#include <unistd.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <net/if.h>#include <sys/ioctl.h>#include "isns.h"#include "iscsid.h"static int cur_transaction_id = 0;int sock_fd = -1;int use_tcp = 1;int isns_port = ISNS_PORT;int use_isns = 0;struct network_entity *iet_entity = NULL;struct portal *iet_portal = NULL;/* * wrapper to hide the TCP or UDP detail. currently we use TCP only */int send_data(char *buf, int size){	int i = 0;	if (sock_fd == -1) {		log_error("Wrong sock.\n");		return -EINVAL;	}	do {		buf += i;		if ((i = send(sock_fd, buf, size, 0)) == -1) {			log_error("Send data fail\n");			return -EIO;		}		size -= i;		if (size < 0) {			log_error("What's wrong? \n");			return -EIO;		}	} while (size);	return 0;}/* * wrapper to hide the TCP or UDP detail currently we use TCP only */int recv_data(char *buf, int size){	int i = 0;	if (sock_fd == -1) {		log_error("Wrong sock.\n");		return -EINVAL;	}	if ((i = recv(sock_fd, buf, size, 0)) == -1) {		log_error("Recv data fail\n");		return -EIO;	}	return i;}int init_isns_connection(int *fd, char *isnsip){	struct sockaddr_in isns_addr;	struct in_addr isns_in_addr;	if (use_tcp) {		if ((*fd = socket (AF_INET, SOCK_STREAM, 0)) < 0) {			log_error("fail to create socket\n");			return -EIO;		}		isns_addr.sin_family = AF_INET;		isns_addr.sin_port = htons((short)isns_port);		if (!inet_aton(isnsip, &isns_in_addr)) {			log_error("invalid isns ip\n");			return -EINVAL;		}		isns_addr.sin_addr.s_addr = isns_in_addr.s_addr;		if (connect(*fd, (struct sockaddr *) &isns_addr, sizeof (isns_addr)) < 0) {			log_error("fail to connect isns server\n");			return -EIO;		}	}	else {		log_error("Unimplemented yet\n");		return -EINVAL;	}	return 0;}void cleanup_connection(int fd){	close(fd);}int send_pdu(struct isns_pdu *pdu, int pdu_size){	/* FIXME: Lock protection */	return send_data((char *)pdu->hdr, pdu_size);}int send_cmd(struct isns_cmd *cmd){	return send_pdu(&cmd->pdu, cmd->cmd_size);}int recv_resp(struct isns_resp *resp, int function_id){	int res;	resp->resp_size = recv_data((char *)resp->pdu.hdr, MAX_ISNS_RESP_SIZE);	log_debug(1, "recv %d\n", resp->resp_size);	if (check_isns_hdr(resp->pdu.hdr, function_id)) {		log_error("Invalid pdu hdr\n");		return -EIO;	}	if ((res = check_isns_resp_status(&resp->pdu)) != ISNSP_RSP_SUCC) {		log_error("fail request %d with status code %d\n", function_id, res);		return -1;	}	return 0;}void init_tvllist(TLVLIST *p, int count){	int i;	if (count > MAX_TLV_CNT) {		log_error("Invalid tlv count\n");		return;	}	for (i = 0; i < count; i++) {		p->tlv[i].attr_tag = INVALID_TAG;		p->tlv[i].attr_len = NULL_SIZE;		memset(p->tlv[i].attr_val, 0, MAX_TLV_VALUE_LEN);	}}char *append_tlv(char *cur_buf, const struct tag_len_val *tlv){	if (!cur_buf) {		log_error("Invalid cur_buf in append_tlv\n");		return cur_buf;	}	if (!tlv) {		log_error("Invalid NULL tlv in append_tlv\n");		return cur_buf;	}	if (tlv->attr_tag == INVALID_TAG)		return cur_buf;	if (tlv->attr_tag == ATTR_TAG_EID)		log_debug(2, "attach EID: %ld,%s\n", tlv->attr_len, tlv->attr_val);	*((u32 *)cur_buf) = htonl(tlv->attr_tag);	*((u32 *)cur_buf + 1) = htonl(tlv->attr_len);	if (tlv->attr_len)		memcpy(cur_buf + 8, (char *)tlv->attr_val, tlv->attr_len);	return (cur_buf + tlv->attr_len + 8);}int set_tlv_u32_data(struct tag_len_val *tvl, u32 data, u32 tag, long size){	if (!tvl)		return -EINVAL;	/* keep tag and length in host order while data in network order */	tvl->attr_tag = tag;	tvl->attr_len = size;	*(u32 *)tvl->attr_val = htonl(data);	return 0;}int set_tlv_ip_data(struct tag_len_val *tvl, char *ip, u32 tag, long size){	struct in_addr portal_ip;	tvl->attr_tag = tag;	tvl->attr_len = size;	if (inet_aton(ip, &portal_ip)) {		*((u32 *)tvl->attr_val) = 0x0;		*((u32 *)tvl->attr_val + 1) = 0x0;		*((u32 *)tvl->attr_val + 2) = htonl(0xFFFF);		*((u32 *)tvl->attr_val + 3) = portal_ip.s_addr;		return 0;	}	else {		log_error("invalid ip\n");		return -EINVAL;	}}int set_tlv_string_data(struct tag_len_val *tvl, char *data, u16 tag, int maxlen){	tvl->attr_tag = tag;	tvl->attr_len = (data) ? Four_Bytes_Aligned(strlen(data)) : 0;	if (tvl->attr_len > maxlen) {		log_error("Wrong size of string data\n");		return -EINVAL;	}	else {		if (tvl->attr_len) {			memset(tvl->attr_val, 0, tvl->attr_len);			strcpy(tvl->attr_val, data);		}		return 0;	}}#define init_network_entity(x) init_tvllist((TLVLIST *)x, 9)#define set_tlv_entity_id(x, y) 		\	set_tlv_string_data(x, y, ATTR_TAG_EID, ATTR_TAG_EID_SIZE)#define set_tlv_entity_proto(x, y)	\	set_tlv_u32_data(x, y, ATTR_TAG_ENTITY_PROTO, ATTR_TAG_ENTITY_PROTO_SIZE)#define set_tlv_manage_ip(x, y)	\	set_tlv_ip_data(x, y, ATTR_TAG_MANA_IP_ADDR, ATTR_TAG_MANA_IP_ADDR_SIZE)#define init_storage_node(x) init_tvllist((TLVLIST *)x, 8)#define set_tlv_iscsi_name(x, y) 		\	set_tlv_string_data(x, y, ATTR_TAG_ISCSI_NAME, ATTR_TAG_ISCSI_NAME_SIZE)#define set_tlv_iscsi_alias(x, y) 		\	set_tlv_string_data(x, y, ATTR_TAG_ISCSI_ALIAS, ATTR_TAG_ISCSI_ALIAS_SIZE)#define set_tlv_iscsi_auth_method(x, y) 		\	set_tlv_string_data(x, y, ATTR_TAG_ISCSI_AUTH_METHOD, ATTR_TAG_ISCSI_AUTH_METHOD_SIZE)#define set_tlv_iscsi_node_type(x, y)	\	set_tlv_u32_data(x, 1UL << (31 - (y)), ATTR_TAG_NODE_TYPE, ATTR_TAG_NODE_TYPE_SIZE)#define init_portal(x) init_tvllist((TLVLIST *)x, 11)#define set_tlv_portal_ip(x, y)	\	set_tlv_ip_data(x, y, ATTR_TAG_PORTAL_IP_ADDR, ATTR_TAG_PORTAL_IP_ADDR_SIZE)#define set_tlv_portal_port(x, y)	\	set_tlv_u32_data(x, y, ATTR_TAG_PORTAL_PORT, ATTR_TAG_PORTAL_PORT_SIZE)#define init_portal_group(x) init_tvllist((TLVLIST *)x, 5)#define set_tlv_pg_iscsi_name(x, y)	\	set_tlv_string_data(x, y, ATTR_TAG_PG_ISCSI_NAME, ATTR_TAG_PG_ISCSI_NAME_SIZE)#define set_tlv_pg_portal_ip(x, y)	\	set_tlv_ip_data(x, y, ATTR_TAG_PG_PORTAL_IP_ADDR, ATTR_TAG_PG_PORTAL_IP_ADDR_SIZE)#define set_tlv_pg_portal_port(x, y)	\	set_tlv_u32_data(x, y, ATTR_TAG_PG_PORTAL_PORT, ATTR_TAG_PG_PORTAL_PORT_SIZE)#define set_tlv_pg_tag(x, y)	\	set_tlv_u32_data(x, y, ATTR_TAG_PG_TAG, ATTR_TAG_PG_TAG_SIZE)#define init_discovery_domain(x) init_tvllist((TLVLIST *)x, 8)#define init_discovery_domain_set(x) init_tvllist((TLVLIST *)x, 3)int initialize_iet_entity(struct network_entity *entity){	init_network_entity(entity);	set_tlv_entity_proto(&entity->entity_proto, EP_ISCSI);	return set_tlv_entity_id(&entity->eid, NULL);}int initialize_iet_portal(int port){	int err;	int fd;	struct ifreq ifr;	int i;	struct portal *p;	fd = socket(PF_INET, SOCK_DGRAM, 0);	if (fd < 0) {		log_error("Can not create socket \n");		return -EIO;	}	for (i = 0; i < 8; i++) {		sprintf(ifr.ifr_name, "eth%d", i);		ifr.ifr_addr.sa_family = AF_INET;		if (ioctl(fd, SIOCGIFADDR, &ifr) == 0) {			if (!(p = (struct portal *)malloc(sizeof(struct portal)))) {				log_error("can not get memory for portal\n");				err = -ENOMEM;				break;			}			set_tlv_portal_ip(&p->portal_ip_addr, inet_ntoa(((struct sockaddr_in *)&(ifr.ifr_addr))->sin_addr));			set_tlv_portal_port(&p->portal_port, port);			p->next = iet_portal;			iet_portal = p;		}		else {			log_error("fail to get ip address for eth%d\n", i);			break;		}	}	close(fd);	return 0;}int initialize_iet_isns(char *isnsip, int port){	int err;	struct portal *p;	/*	 * FIXME: currently only support one entity and one portal.	 */	if (!(iet_entity = (struct network_entity *)malloc(sizeof(struct network_entity)))) {		log_error("can not get memory for iet_entity\n");		return -ENOMEM;	}	if ((err = initialize_iet_entity(iet_entity)))		goto fail;	if ((err = initialize_iet_portal(port)))		goto fail;	if ((err = init_isns_connection(&sock_fd, isnsip)))		goto fail;	return 0;fail:	if (iet_entity)		free(iet_entity);	while (iet_portal) {		p = iet_portal->next;		free(iet_portal);		iet_portal = p;	};	return err;}void cleanup_iet_isns(void){	struct portal *p;	cleanup_connection(sock_fd);	if (iet_entity)		free(iet_entity);	while (iet_portal) {		p = iet_portal->next;		free(iet_portal);		iet_portal = p;	};}void get_next_transaction_id(u16 *transaction_id){	/* FIXME: Lock protection */	*transaction_id = cur_transaction_id++;}void get_cur_transaction_id(u16 *transaction_id){	/* FIXME: Lock protection */	*transaction_id = cur_transaction_id;}struct isns_cmd *allocate_isns_cmd(void)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -