📄 iscsi-slp-discovery.c
字号:
#include <unistd.h>#include <slp.h>#include "iscsi-sfnet.h"#include "iscsi-slp-discovery.h"#define ISCSI_SERVICE "service:iscsi:target"#define MAX_IFACES 10#define IP_ADDR_LEN 16#define RECORD_LEN 2048#define PREDICATE_LEN 2048#define CRED_PREDICATE_LEN 512#define NAME_PREDICATE_LEN 512#define INITIATOR_NAME "/etc/initiatorname.iscsi"static int record_begin;struct InterfaceInfo { int iface_count; struct sockaddr_in iface_addr[MAX_IFACES];};struct slp_portal { struct slp_portal *next; char *ip; char *port; char *tag;};struct slp_target { struct slp_target *next; char *target_name; struct slp_portal *portals; struct slp_portal *tail;};struct slp_discovery_process { struct slp_discovery_process *next; struct slp_target *targets; struct slp_target *tail; struct iscsi_discovery_process *discovery;};struct slp_discovery_process_list { struct slp_discovery_process *head; struct slp_discovery_process *tail;};struct slp_discovery_pg_cookie { struct iscsi_discovery_process *discovery; char *target_name; char *ip; char *port;};struct slp_discovery_process_list *list = NULL;voidadd_slp_portal(struct slp_target *target, char *ip, char *port, char *tag){ struct slp_portal *portal = (struct slp_portal *) malloc(sizeof (struct slp_portal)); portal->ip = ip; portal->port = port; portal->tag = tag; portal->next = NULL; target->tail->next = portal; target->tail = portal; debugmsg(7, "slp portal %p added\n", portal);}voidadd_slp_target(struct slp_discovery_process *process, char *name, char *ip, char *port, char *tag){ struct slp_target *target = NULL; struct slp_portal *portal = NULL; target = (struct slp_target *) malloc(sizeof (struct slp_target)); portal = (struct slp_portal *) malloc(sizeof (struct slp_portal)); target->target_name = name; target->portals = target->tail = portal; target->next = NULL; portal->ip = ip; portal->port = port; portal->tag = tag; portal->next = NULL; process->tail->next = target; process->tail = target; debugmsg(7, "slp target %s added\n", target->target_name);}voidadd_slp_discovery_process(struct iscsi_discovery_process *discovery, char *name, char *ip, char *port, char *tag){ struct slp_discovery_process *process; struct slp_target *target; struct slp_portal *portal; process = (struct slp_discovery_process *) malloc(sizeof (struct slp_discovery_process)); target = (struct slp_target *) malloc(sizeof (struct slp_target)); portal = (struct slp_portal *) malloc(sizeof (struct slp_portal)); process->discovery = discovery; process->targets = process->tail = target; process->next = NULL; target->target_name = name; target->portals = target->tail = portal; target->next = NULL; portal->ip = ip; portal->port = port; portal->tag = tag; portal->next = NULL; if (list) { list->tail->next = process; list->tail = process; } else { list = (struct slp_discovery_process_list *) malloc(sizeof (struct slp_discovery_process_list)); list->head = list->tail = process; } debugmsg(7, "slp discovery data buffered for discovery process: %d\n", discovery->pid);}voidsave_slp_discovery_data(char *name, char *ip, char *port, char *tag, struct iscsi_discovery_process *discovery){ struct slp_discovery_process *process; struct slp_target *target = NULL; int slp_discovery_process_exit = 0; int slp_target_exit = 0; if (list) { for (process = list->head; process; process = process->next) { if (process->discovery == discovery) { slp_discovery_process_exit = 1; for (target = process->targets; target; target = target->next) { if (strcmp(target->target_name, name) == 0) { slp_target_exit = 1; break; } } break; } } if (slp_discovery_process_exit) { if (slp_target_exit) add_slp_portal(target, ip, port, tag); else add_slp_target(process, name, ip, port, tag); } else add_slp_discovery_process(discovery, name, ip, port, tag); } else add_slp_discovery_process(discovery, name, ip, port, tag);}voidsend_target_record(struct slp_target *target, struct iscsi_discovery_process *discovery){ struct slp_portal *portal; char record[RECORD_LEN]; char *c = record; int len = 0; int result; memset(record, 0, RECORD_LEN); if (!record_begin) { sprintf(c, "DTN=%s\n", target->target_name); record_begin = 1; } else { sprintf(c, "TN=%s\n", target->target_name); } len += strlen(c); c += strlen(c); for (portal = target->portals; portal; portal = portal->next) { sprintf(c, "TT=%s\n", portal->tag); len += strlen(c); c += strlen(c); sprintf(c, "TP=%s\n", portal->port); len += strlen(c); c += strlen(c); sprintf(c, "TA=%s\n", portal->ip); len += strlen(c); c += strlen(c); } sprintf(c, ";\n"); len += strlen(c); debugmsg(7, "sending target record %s\n", record); result = write(discovery->pipe_fd, record, len); if (result < 0) logmsg(AS_ERROR, "Error in sending discovery data for target %s " "by discovery process %d\n", target->target_name, discovery->pid);}voidfree_slp_portals(struct slp_portal *portals){ struct slp_portal *portal; while (portals) { portal = portals; if (portal->ip) free(portal->ip); if (portal->port) free(portal->port); if (portal->tag) free(portal->tag); portals = portals->next; free(portal); }}voidfree_slp_targets(struct slp_target *targets){ struct slp_target *target; while (targets) { target = targets; if (target->target_name) free(target->target_name); if (target->tail) target->tail = NULL; if (target->portals) free_slp_portals(target->portals); targets = targets->next; free(target); }}voidfree_slp_discovery_process(struct slp_discovery_process *process){ struct slp_discovery_process *p; struct slp_discovery_process *n; if (process) { if (process->targets) { process->tail = NULL; free_slp_targets(process->targets); } for (n = list->head, p = list->head; n; n = n->next) { if (n == process) { if (n == p) /* head */ list->head = process->next; else p->next = n->next; if (n == list->tail) { if (n == p) /* this is the only * process in list */ list->tail = list->head; else list->tail = p; } process->discovery = NULL; free(process); break; } p = n; } }}voidsend_slp_discovery_data(struct iscsi_discovery_process *discovery){ struct slp_discovery_process *process; struct slp_target *target; if (list) { for (process = list->head; process; process = process->next) { if (process->discovery == discovery) { for (target = process->targets; target; target = target->next) { send_target_record(target, discovery); } write(discovery->pipe_fd, "!\n", sizeof ("!\n") - 1); record_begin = 0; break; } } }}voidfree_slp_discovery_data(struct iscsi_discovery_process *discovery){ struct slp_discovery_process *process; if (list) { for (process = list->head; process; process = process->next) { if (process->discovery == discovery) { free_slp_discovery_process(process); break; } } if ((list->head == NULL) && (list->tail == NULL)) { free(list); list = NULL; } }}intIfaceGetInfo(struct InterfaceInfo *ifaceinfo, struct iscsi_discovery_process *discovery){ struct sockaddr *sa; struct sockaddr_in *sin; struct ifreq ifrlist[MAX_IFACES]; struct ifreq ifrflags; struct ifconf ifc; int fd; int i; ifc.ifc_len = sizeof (struct ifreq) * MAX_IFACES; ifc.ifc_req = ifrlist; fd = socket(AF_INET, SOCK_STREAM, 0); if (fd == -1) { logmsg(AS_ERROR, "Failed to create socket, for getting all IP interfaces " "through discovery process pid = %d\n", discovery->pid); return -1; } if (ioctl(fd, SIOCGIFCONF, &ifc) == -1) { logmsg(AS_ERROR, "ioctl failure, in getting all IP interfaces through " "discovery process pid = %d\n", discovery->pid); return -1; } memset(ifaceinfo, 0, sizeof (struct InterfaceInfo)); for (i = 0; i < ifc.ifc_len / sizeof (struct ifreq); i++) { sa = (struct sockaddr *) &(ifrlist[i].ifr_addr); if (sa->sa_family == AF_INET) { /* Get interface flags */ memcpy(&ifrflags, &(ifrlist[i]), sizeof (struct ifreq)); if (ioctl(fd, SIOCGIFFLAGS, &ifrflags) == 0) { /* skip the loopback interfaces */ if ((ifrflags.ifr_flags & IFF_LOOPBACK) == 0) { sin = (struct sockaddr_in *) sa; memcpy(& (ifaceinfo-> iface_addr[ifaceinfo-> iface_count]), sin, sizeof (struct sockaddr_in)); ifaceinfo->iface_count++; } } } } return 0;}char *get_all_ip(struct iscsi_discovery_process *discovery){ int i; struct InterfaceInfo ifaceinfo; char *addrstr = NULL; if (IfaceGetInfo(&ifaceinfo, discovery) == 0) { addrstr = (char *) malloc(ifaceinfo.iface_count * IP_ADDR_LEN); memset(addrstr, 0, ifaceinfo.iface_count * IP_ADDR_LEN); for (i = 0; i < ifaceinfo.iface_count; i++) { strcat(addrstr, inet_ntoa(ifaceinfo.iface_addr[i].sin_addr)); if (i + 1 < ifaceinfo.iface_count) { strcat(addrstr, ","); } } } return addrstr;}SLPBooleanSrvUrlCallback(SLPHandle hslp, const char *srvurl, unsigned short lifetime, int errcode, void *cookie){ char *target_name, *targetname; char *ip; char *port, *port_id; char *tmp_url, *start_url= NULL, *attr_url; struct iscsi_discovery_process *discovery = NULL; char *addr; char *tag; if (errcode == SLP_OK) { debugmsg(7, "SLP url :%s,%i\n", srvurl, lifetime); } if (srvurl) start_url = strdup(srvurl); tmp_url = start_url; if (cookie) discovery = (struct iscsi_discovery_process *) cookie; if (tmp_url) { attr_url = strdup(tmp_url); if (strncmp(tmp_url, "service:iscsi:target://", 23) == 0) { tmp_url += 22; *tmp_url = '\0'; tmp_url++; ip = tmp_url; port = strchr(tmp_url, ':'); *port = '\0'; port++; tmp_url = port; target_name = strchr(tmp_url, '/'); *target_name = '\0'; target_name++; tmp_url = target_name; debugmsg(7, "iSCSI Target: ip %s port %s target name %s, " "discovered by discovery process %d\n", ip, port, target_name, discovery->pid); /* slp query do not return any information related to * target tag. For time being setting it to 1. */ addr = (char *) malloc(strlen(ip) + 1); memset(addr, 0, strlen(ip) + 1); memcpy(addr, ip, strlen(ip)); port_id = (char *) malloc(strlen(port) + 1); memset(port_id, 0, strlen(port) + 1); memcpy(port_id, port, strlen(port)); targetname = (char *) malloc(strlen(target_name) + 1); memset(targetname, 0, strlen(target_name) + 1); memcpy(targetname, target_name, strlen(target_name)); tag = (char *) malloc(strlen("0") + 1); memset(tag, 0, strlen("0") + 1); strcpy(tag, "1"); save_slp_discovery_data(targetname, addr, port_id, tag, discovery); if ( discovery->flag == SLP_UNICAST_ENABLED ) slp_unicast_attr_query(discovery, attr_url, "portal-group", targetname, addr, port_id); if ( discovery->flag == SLP_MULTICAST_ENABLED ) slp_multicast_attr_query(discovery, attr_url, "portal-group", targetname, addr, port_id);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -