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

📄 connect.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 5 页
字号:
	struct cifsTconInfo *tcon;	read_lock(&GlobalSMBSeslock);	list_for_each(tmp, &GlobalTreeConnectionList) {		cFYI(1, ("Next tcon - "));		tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);		if (tcon->ses) {			if (tcon->ses->server) {				cFYI(1,				     (" old ip addr: %x == new ip %x ?",				      tcon->ses->server->addr.sockAddr.sin_addr.				      s_addr, new_target_ip_addr));				if (tcon->ses->server->addr.sockAddr.sin_addr.				    s_addr == new_target_ip_addr) {	/* BB lock tcon and server and tcp session and increment use count here? */					/* found a match on the TCP session */					/* BB check if reconnection needed */					cFYI(1,("Matched ip, old UNC: %s == new: %s ?",					      tcon->treeName, uncName));					if (strncmp					    (tcon->treeName, uncName,					     MAX_TREE_SIZE) == 0) {						cFYI(1,						     ("Matched UNC, old user: %s == new: %s ?",						      tcon->treeName, uncName));						if (strncmp						    (tcon->ses->userName,						     userName,						     MAX_USERNAME_SIZE) == 0) {							read_unlock(&GlobalSMBSeslock);							return tcon;/* also matched user (smb session)*/						}					}				}			}		}	}	read_unlock(&GlobalSMBSeslock);	return NULL;}intconnect_to_dfs_path(int xid, struct cifsSesInfo *pSesInfo,		    const char *old_path, const struct nls_table *nls_codepage){	unsigned char *referrals = NULL;	unsigned int num_referrals;	int rc = 0;	rc = get_dfs_path(xid, pSesInfo,old_path, nls_codepage, 			&num_referrals, &referrals);	/* BB Add in code to: if valid refrl, if not ip address contact		the helper that resolves tcp names, mount to it, try to 		tcon to it unmount it if fail */	if(referrals)		kfree(referrals);	return rc;}intget_dfs_path(int xid, struct cifsSesInfo *pSesInfo,			const char *old_path, const struct nls_table *nls_codepage, 			unsigned int *pnum_referrals, unsigned char ** preferrals){	char *temp_unc;	int rc = 0;	*pnum_referrals = 0;	if (pSesInfo->ipc_tid == 0) {		temp_unc = kmalloc(2 /* for slashes */ +			strnlen(pSesInfo->serverName,SERVER_NAME_LEN_WITH_NULL * 2)				 + 1 + 4 /* slash IPC$ */  + 2,				GFP_KERNEL);		if (temp_unc == NULL)			return -ENOMEM;		temp_unc[0] = '\\';		temp_unc[1] = '\\';		strcpy(temp_unc + 2, pSesInfo->serverName);		strcpy(temp_unc + 2 + strlen(pSesInfo->serverName), "\\IPC$");		rc = CIFSTCon(xid, pSesInfo, temp_unc, NULL, nls_codepage);		cFYI(1,		     ("CIFS Tcon rc = %d ipc_tid = %d", rc,pSesInfo->ipc_tid));		kfree(temp_unc);	}	if (rc == 0)		rc = CIFSGetDFSRefer(xid, pSesInfo, old_path, preferrals,				     pnum_referrals, nls_codepage);	return rc;}/* See RFC1001 section 14 on representation of Netbios names */static void rfc1002mangle(char * target,char * source, unsigned int length){	unsigned int i,j;	for(i=0,j=0;i<(length);i++) {		/* mask a nibble at a time and encode */		target[j] = 'A' + (0x0F & (source[i] >> 4));		target[j+1] = 'A' + (0x0F & source[i]);		j+=2;	}}static intipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket, 			 char * netbios_name){	int rc = 0;	int connected = 0;	__be16 orig_port = 0;	if(*csocket == NULL) {		rc = sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, csocket);		if (rc < 0) {			cERROR(1, ("Error %d creating socket",rc));			*csocket = NULL;			return rc;		} else {		/* BB other socket options to set KEEPALIVE, NODELAY? */			cFYI(1,("Socket created"));			(*csocket)->sk->sk_allocation = GFP_NOFS; 		}	}	psin_server->sin_family = AF_INET;	if(psin_server->sin_port) { /* user overrode default port */		rc = (*csocket)->ops->connect(*csocket,				(struct sockaddr *) psin_server,				sizeof (struct sockaddr_in),0);		if (rc >= 0)			connected = 1;	} 	if(!connected) {		/* save original port so we can retry user specified port  			later if fall back ports fail this time  */		orig_port = psin_server->sin_port;		/* do not retry on the same port we just failed on */		if(psin_server->sin_port != htons(CIFS_PORT)) {			psin_server->sin_port = htons(CIFS_PORT);			rc = (*csocket)->ops->connect(*csocket,					(struct sockaddr *) psin_server,					sizeof (struct sockaddr_in),0);			if (rc >= 0)				connected = 1;		}	}	if (!connected) {		psin_server->sin_port = htons(RFC1001_PORT);		rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *)					      psin_server, sizeof (struct sockaddr_in),0);		if (rc >= 0) 			connected = 1;	}	/* give up here - unless we want to retry on different		protocol families some day */	if (!connected) {		if(orig_port)			psin_server->sin_port = orig_port;		cFYI(1,("Error %d connecting to server via ipv4",rc));		sock_release(*csocket);		*csocket = NULL;		return rc;	}	/* Eventually check for other socket options to change from 		the default. sock_setsockopt not used because it expects 		user space buffer */	(*csocket)->sk->sk_rcvtimeo = 7 * HZ;	/* send RFC1001 sessinit */	if(psin_server->sin_port == htons(RFC1001_PORT)) {		/* some servers require RFC1001 sessinit before sending		negprot - BB check reconnection in case where second 		sessinit is sent but no second negprot */		struct rfc1002_session_packet * ses_init_buf;		struct smb_hdr * smb_buf;		ses_init_buf = cifs_kcalloc(sizeof(struct rfc1002_session_packet), GFP_KERNEL);		if(ses_init_buf) {			ses_init_buf->trailer.session_req.called_len = 32;			rfc1002mangle(ses_init_buf->trailer.session_req.called_name,				DEFAULT_CIFS_CALLED_NAME,16);			ses_init_buf->trailer.session_req.calling_len = 32;			/* calling name ends in null (byte 16) from old smb			convention. */			if(netbios_name && (netbios_name[0] !=0)) {				rfc1002mangle(ses_init_buf->trailer.session_req.calling_name,					netbios_name,16);			} else {				rfc1002mangle(ses_init_buf->trailer.session_req.calling_name,					"LINUX_CIFS_CLNT",16);			}			ses_init_buf->trailer.session_req.scope1 = 0;			ses_init_buf->trailer.session_req.scope2 = 0;			smb_buf = (struct smb_hdr *)ses_init_buf;			/* sizeof RFC1002_SESSION_REQUEST with no scope */			smb_buf->smb_buf_length = 0x81000044;			rc = smb_send(*csocket, smb_buf, 0x44,				(struct sockaddr *)psin_server);			kfree(ses_init_buf);		}		/* else the negprot may still work without this 		even though malloc failed */			}			return rc;}static intipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket){	int rc = 0;	int connected = 0;	__be16 orig_port = 0;	if(*csocket == NULL) {		rc = sock_create_kern(PF_INET6, SOCK_STREAM, IPPROTO_TCP, csocket);		if (rc < 0) {			cERROR(1, ("Error %d creating ipv6 socket",rc));			*csocket = NULL;			return rc;		} else {		/* BB other socket options to set KEEPALIVE, NODELAY? */			 cFYI(1,("ipv6 Socket created"));			(*csocket)->sk->sk_allocation = GFP_NOFS;		}	}	psin_server->sin6_family = AF_INET6;	if(psin_server->sin6_port) { /* user overrode default port */		rc = (*csocket)->ops->connect(*csocket,				(struct sockaddr *) psin_server,				sizeof (struct sockaddr_in6),0);		if (rc >= 0)			connected = 1;	} 	if(!connected) {		/* save original port so we can retry user specified port  			later if fall back ports fail this time  */		orig_port = psin_server->sin6_port;		/* do not retry on the same port we just failed on */		if(psin_server->sin6_port != htons(CIFS_PORT)) {			psin_server->sin6_port = htons(CIFS_PORT);			rc = (*csocket)->ops->connect(*csocket,					(struct sockaddr *) psin_server,					sizeof (struct sockaddr_in6),0);			if (rc >= 0)				connected = 1;		}	}	if (!connected) {		psin_server->sin6_port = htons(RFC1001_PORT);		rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *)					 psin_server, sizeof (struct sockaddr_in6),0);		if (rc >= 0) 			connected = 1;	}	/* give up here - unless we want to retry on different		protocol families some day */	if (!connected) {		if(orig_port)			psin_server->sin6_port = orig_port;		cFYI(1,("Error %d connecting to server via ipv6",rc));		sock_release(*csocket);		*csocket = NULL;		return rc;	}	/* Eventually check for other socket options to change from 		the default. sock_setsockopt not used because it expects 		user space buffer */	(*csocket)->sk->sk_rcvtimeo = 7 * HZ;			return rc;}intcifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,	   char *mount_data, const char *devname){	int rc = 0;	int xid;	int address_type = AF_INET;	struct socket *csocket = NULL;	struct sockaddr_in sin_server;	struct sockaddr_in6 sin_server6;	struct smb_vol volume_info;	struct cifsSesInfo *pSesInfo = NULL;	struct cifsSesInfo *existingCifsSes = NULL;	struct cifsTconInfo *tcon = NULL;	struct TCP_Server_Info *srvTcp = NULL;	xid = GetXid();/* cFYI(1, ("Entering cifs_mount. Xid: %d with: %s", xid, mount_data)); */		memset(&volume_info,0,sizeof(struct smb_vol));	if (cifs_parse_mount_options(mount_data, devname, &volume_info)) {		if(volume_info.UNC)			kfree(volume_info.UNC);		if(volume_info.password)			kfree(volume_info.password);		FreeXid(xid);		return -EINVAL;	}	if (volume_info.username) {		cFYI(1, ("Username: %s ", volume_info.username));	} else {		cifserror("No username specified ");        /* In userspace mount helper we can get user name from alternate           locations such as env variables and files on disk */		if(volume_info.UNC)			kfree(volume_info.UNC);		if(volume_info.password)			kfree(volume_info.password);		FreeXid(xid);		return -EINVAL;	}	if (volume_info.UNCip && volume_info.UNC) {		rc = cifs_inet_pton(AF_INET, volume_info.UNCip,&sin_server.sin_addr.s_addr);		if(rc <= 0) {			/* not ipv4 address, try ipv6 */			rc = cifs_inet_pton(AF_INET6,volume_info.UNCip,&sin_server6.sin6_addr.in6_u); 			if(rc > 0)				address_type = AF_INET6;		} else {			address_type = AF_INET;		}       		if(rc <= 0) {			/* we failed translating address */			if(volume_info.UNC)				kfree(volume_info.UNC);			if(volume_info.password)				kfree(volume_info.password);			FreeXid(xid);			return -EINVAL;		}		cFYI(1, ("UNC: %s ip: %s", volume_info.UNC, volume_info.UNCip));		/* success */		rc = 0;	} else if (volume_info.UNCip){		/* BB using ip addr as server name connect to the DFS root below */		cERROR(1,("Connecting to DFS root not implemented yet"));		if(volume_info.UNC)			kfree(volume_info.UNC);		if(volume_info.password)			kfree(volume_info.password);		FreeXid(xid);		return -EINVAL;	} else /* which servers DFS root would we conect to */ {		cERROR(1,		       ("CIFS mount error: No UNC path (e.g. -o unc=//192.168.1.100/public) specified  "));		if(volume_info.UNC)			kfree(volume_info.UNC);		if(volume_info.password)			kfree(volume_info.password);		FreeXid(xid);		return -EINVAL;	}	/* this is needed for ASCII cp to Unicode converts */	if(volume_info.iocharset == NULL) {		cifs_sb->local_nls = load_nls_default();	/* load_nls_default can not return null */	} else {		cifs_sb->local_nls = load_nls(volume_info.iocharset);		if(cifs_sb->local_nls == NULL) {			cERROR(1,("CIFS mount error: iocharset %s not found",volume_info.iocharset));			if(volume_info.UNC)				kfree(volume_info.UNC);			if(volume_info.password)				kfree(volume_info.password);			FreeXid(xid);			return -ELIBACC;		}	}	if(address_type == AF_INET)		existingCifsSes = cifs_find_tcp_session(&sin_server.sin_addr,			NULL /* no ipv6 addr */,			volume_info.username, &srvTcp);	else if(address_type == AF_INET6)		existingCifsSes = cifs_find_tcp_session(NULL /* no ipv4 addr */,			&sin_server6.sin6_addr,			volume_info.username, &srvTcp);	else {		if(volume_info.UNC)			kfree(volume_info.UNC);		if(volume_info.password)			kfree(volume_info.password);		FreeXid(xid);		return -EINVAL;	}	if (srvTcp) {		cFYI(1, ("Existing tcp session with server found "));                	} else {	/* create socket */		if(volume_info.port)			sin_server.sin_port = htons(volume_info.port);		else			sin_server.sin_port = 0;		rc = ipv4_connect(&sin_server,&csocket,volume_info.source_rfc1001_name);		if (rc < 0) {			cERROR(1,			       ("Error connecting to IPv4 socket. Aborting operation"));

⌨️ 快捷键说明

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