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

📄 nmblib.c

📁 samba-3.0.22.tar.gz 编译smb服务器的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
	RSSVAL(ubuf,offset,nmb->header.name_trn_id);	ubuf[offset+2] = (nmb->header.opcode & 0xF) << 3;	if (nmb->header.response)		ubuf[offset+2] |= (1<<7);	if (nmb->header.nm_flags.authoritative && 			nmb->header.response)		ubuf[offset+2] |= 0x4;	if (nmb->header.nm_flags.trunc)		ubuf[offset+2] |= 0x2;	if (nmb->header.nm_flags.recursion_desired)		ubuf[offset+2] |= 0x1;	if (nmb->header.nm_flags.recursion_available &&			nmb->header.response)		ubuf[offset+3] |= 0x80;	if (nmb->header.nm_flags.bcast)		ubuf[offset+3] |= 0x10;	ubuf[offset+3] |= (nmb->header.rcode & 0xF);	RSSVAL(ubuf,offset+4,nmb->header.qdcount);	RSSVAL(ubuf,offset+6,nmb->header.ancount);	RSSVAL(ubuf,offset+8,nmb->header.nscount);	RSSVAL(ubuf,offset+10,nmb->header.arcount);  	offset += 12;	if (nmb->header.qdcount) {		/* XXXX this doesn't handle a qdcount of > 1 */		offset += put_nmb_name((char *)ubuf,offset,&nmb->question.question_name);		RSSVAL(ubuf,offset,nmb->question.question_type);		RSSVAL(ubuf,offset+2,nmb->question.question_class);		offset += 4;	}	if (nmb->header.ancount)		offset += put_res_rec((char *)ubuf,offset,nmb->answers,				nmb->header.ancount);	if (nmb->header.nscount)		offset += put_res_rec((char *)ubuf,offset,nmb->nsrecs,				nmb->header.nscount);	/*	 * The spec says we must put compressed name pointers	 * in the following outgoing packets :	 * NAME_REGISTRATION_REQUEST, NAME_REFRESH_REQUEST,	 * NAME_RELEASE_REQUEST.	 */	if((nmb->header.response == False) &&			((nmb->header.opcode == NMB_NAME_REG_OPCODE) ||			(nmb->header.opcode == NMB_NAME_RELEASE_OPCODE) ||			(nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_8) ||			(nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_9) ||			(nmb->header.opcode == NMB_NAME_MULTIHOMED_REG_OPCODE)) &&			(nmb->header.arcount == 1)) {		offset += put_compressed_name_ptr(ubuf,offset,nmb->additional,12);	} else if (nmb->header.arcount) {		offset += put_res_rec((char *)ubuf,offset,nmb->additional,			nmb->header.arcount);  	}	return(offset);}/******************************************************************* Linearise a packet.******************************************************************/int build_packet(char *buf, struct packet_struct *p){	int len = 0;	switch (p->packet_type) {	case NMB_PACKET:		len = build_nmb(buf,p);		break;	case DGRAM_PACKET:		len = build_dgram(buf,p);		break;	}	return len;}/******************************************************************* Send a packet_struct.******************************************************************/BOOL send_packet(struct packet_struct *p){	char buf[1024];	int len=0;	memset(buf,'\0',sizeof(buf));	len = build_packet(buf, p);	if (!len)		return(False);	return(send_udp(p->fd,buf,len,p->ip,p->port));}/**************************************************************************** Receive a packet with timeout on a open UDP filedescriptor. The timeout is in milliseconds***************************************************************************/struct packet_struct *receive_packet(int fd,enum packet_type type,int t){	fd_set fds;	struct timeval timeout;	int ret;	FD_ZERO(&fds);	FD_SET(fd,&fds);	timeout.tv_sec = t/1000;	timeout.tv_usec = 1000*(t%1000);	if ((ret = sys_select_intr(fd+1,&fds,NULL,NULL,&timeout)) == -1) {		/* errno should be EBADF or EINVAL. */		DEBUG(0,("select returned -1, errno = %s (%d)\n", strerror(errno), errno));		return NULL;	}	if (ret == 0) /* timeout */		return NULL;	if (FD_ISSET(fd,&fds)) 		return(read_packet(fd,type));		return(NULL);}/**************************************************************************** Receive a UDP/137 packet either via UDP or from the unexpected packet queue. The packet must be a reply packet and have the specified trn_id. The timeout is in milliseconds.***************************************************************************/struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id){	struct packet_struct *p;	p = receive_packet(fd, NMB_PACKET, t);	if (p && p->packet.nmb.header.response &&			p->packet.nmb.header.name_trn_id == trn_id) {		return p;	}	if (p)		free_packet(p);	/* try the unexpected packet queue */	return receive_unexpected(NMB_PACKET, trn_id, NULL);}/**************************************************************************** Receive a UDP/138 packet either via UDP or from the unexpected packet queue. The packet must be a reply packet and have the specified mailslot name The timeout is in milliseconds.***************************************************************************/struct packet_struct *receive_dgram_packet(int fd, int t, const char *mailslot_name){	struct packet_struct *p;	p = receive_packet(fd, DGRAM_PACKET, t);	if (p && match_mailslot_name(p, mailslot_name)) {		return p;	}	if (p)		free_packet(p);	/* try the unexpected packet queue */	return receive_unexpected(DGRAM_PACKET, 0, mailslot_name);}/**************************************************************************** See if a datagram has the right mailslot name.***************************************************************************/BOOL match_mailslot_name(struct packet_struct *p, const char *mailslot_name){	struct dgram_packet *dgram = &p->packet.dgram;	char *buf;	buf = &dgram->data[0];	buf -= 4;	buf = smb_buf(buf);	if (memcmp(buf, mailslot_name, strlen(mailslot_name)+1) == 0) {		return True;	}	return False;}/**************************************************************************** Return the number of bits that match between two 4 character buffers***************************************************************************/int matching_quad_bits(unsigned char *p1, unsigned char *p2){	int i, j, ret = 0;	for (i=0; i<4; i++) {		if (p1[i] != p2[i])			break;		ret += 8;	}	if (i==4)		return ret;	for (j=0; j<8; j++) {		if ((p1[i] & (1<<(7-j))) != (p2[i] & (1<<(7-j))))			break;		ret++;	}			return ret;}static unsigned char sort_ip[4];/**************************************************************************** Compare two query reply records.***************************************************************************/static int name_query_comp(unsigned char *p1, unsigned char *p2){	return matching_quad_bits(p2+2, sort_ip) - matching_quad_bits(p1+2, sort_ip);}/**************************************************************************** Sort a set of 6 byte name query response records so that the IPs that have the most leading bits in common with the specified address come first.***************************************************************************/void sort_query_replies(char *data, int n, struct in_addr ip){	if (n <= 1)		return;	putip(sort_ip, (char *)&ip);	qsort(data, n, 6, QSORT_CAST name_query_comp);}/******************************************************************* Convert, possibly using a stupid microsoft-ism which has destroyed the transport independence of netbios (for CIFS vendors that usually use the Win95-type methods, not for NT to NT communication, which uses DCE/RPC and therefore full-length unicode strings...) a dns name into a netbios name. The netbios name (NOT necessarily null-terminated) is truncated to 15 characters. ******************************************************************/char *dns_to_netbios_name(const char *dns_name){	static nstring netbios_name;	int i;	StrnCpy(netbios_name, dns_name, MAX_NETBIOSNAME_LEN-1);	netbios_name[15] = 0;		/* ok.  this is because of a stupid microsoft-ism.  if the called host	   name contains a '.', microsoft clients expect you to truncate the	   netbios name up to and including the '.'  this even applies, by	   mistake, to workgroup (domain) names, which is _really_ daft.	 */	for (i = 0; i < 15; i++) {		if (netbios_name[i] == '.') {			netbios_name[i] = 0;			break;		}	}	return netbios_name;}/**************************************************************************** Interpret the weird netbios "name" into a unix fstring. Return the name type.****************************************************************************/static int name_interpret(char *in, fstring name){	int ret;	int len = (*in++) / 2;	fstring out_string;	char *out = out_string;	*out=0;	if (len > 30 || len<1)		return(0);	while (len--) {		if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {			*out = 0;			return(0);		}		*out = ((in[0]-'A')<<4) + (in[1]-'A');		in += 2;		out++;	}	ret = out[-1];	out[-1] = 0;#ifdef NETBIOS_SCOPE	/* Handle any scope names */	while(*in) {		*out++ = '.'; /* Scope names are separated by periods */		len = *(unsigned char *)in++;		StrnCpy(out, in, len);		out += len;		*out=0;		in += len;	}#endif	pull_ascii_fstring(name, out_string);	return(ret);}/**************************************************************************** Mangle a name into netbios format. Note:  <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.****************************************************************************/int name_mangle( char *In, char *Out, char name_type ){	int   i;	int   len;	nstring buf;	char *p = Out;	/* Safely copy the input string, In, into buf[]. */	if (strcmp(In,"*") == 0)		put_name(buf, "*", '\0', 0x00);	else {		/* We use an fstring here as mb dos names can expend x3 when		   going to utf8. */		fstring buf_unix;		nstring buf_dos;		pull_ascii_fstring(buf_unix, In);		strupper_m(buf_unix);		push_ascii_nstring(buf_dos, buf_unix);		put_name(buf, buf_dos, ' ', name_type);	}	/* Place the length of the first field into the output buffer. */	p[0] = 32;	p++;	/* Now convert the name to the rfc1001/1002 format. */	for( i = 0; i < MAX_NETBIOSNAME_LEN; i++ ) {		p[i*2]     = ( (buf[i] >> 4) & 0x000F ) + 'A';		p[(i*2)+1] = (buf[i] & 0x000F) + 'A';	}	p += 32;	p[0] = '\0';	/* Add the scope string. */	for( i = 0, len = 0; *(global_scope()) != '\0'; i++, len++ ) {		switch( (global_scope())[i] ) {			case '\0':				p[0] = len;				if( len > 0 )					p[len+1] = 0;				return( name_len(Out) );			case '.':				p[0] = len;				p   += (len + 1);				len  = -1;				break;			default:				p[len+1] = (global_scope())[i];				break;		}	}	return( name_len(Out) );}/**************************************************************************** Find a pointer to a netbios name.****************************************************************************/static char *name_ptr(char *buf,int ofs){	unsigned char c = *(unsigned char *)(buf+ofs);	if ((c & 0xC0) == 0xC0) {		uint16 l = RSVAL(buf, ofs) & 0x3FFF;		DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));		return(buf + l);	} else {		return(buf+ofs);	}}  /**************************************************************************** Extract a netbios name from a buf (into a unix string) return name type.****************************************************************************/int name_extract(char *buf,int ofs, fstring name){	char *p = name_ptr(buf,ofs);	int d = PTR_DIFF(p,buf+ofs);	name[0] = '\0';	if (d < -50 || d > 50)		return(0);	return(name_interpret(p,name));}  /**************************************************************************** Return the total storage length of a mangled name.****************************************************************************/int name_len(char *s1){	/* NOTE: this argument _must_ be unsigned */	unsigned char *s = (unsigned char *)s1;	int len;	/* If the two high bits of the byte are set, return 2. */	if (0xC0 == (*s & 0xC0))		return(2);	/* Add up the length bytes. */	for (len = 1; (*s); s += (*s) + 1) {		len += *s + 1;		SMB_ASSERT(len < 80);	}	return(len);}

⌨️ 快捷键说明

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