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

📄 nmblib.c

📁 samba-3.0.22.tar.gz 编译smb服务器的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
	if (length < 14)		return(False);	dgram->header.msg_type = CVAL(inbuf,0);	flags = CVAL(inbuf,1);	dgram->header.flags.node_type = (enum node_type)((flags>>2)&3);	if (flags & 1)		dgram->header.flags.more = True;	if (flags & 2)		dgram->header.flags.first = True;	dgram->header.dgm_id = RSVAL(inbuf,2);	putip((char *)&dgram->header.source_ip,inbuf+4);	dgram->header.source_port = RSVAL(inbuf,8);	dgram->header.dgm_length = RSVAL(inbuf,10);	dgram->header.packet_offset = RSVAL(inbuf,12);	offset = 14;	if (dgram->header.msg_type == 0x10 ||			dgram->header.msg_type == 0x11 ||			dgram->header.msg_type == 0x12) {      		offset += parse_nmb_name(inbuf,offset,length,&dgram->source_name);		offset += parse_nmb_name(inbuf,offset,length,&dgram->dest_name);	}	if (offset >= length || (length-offset > sizeof(dgram->data))) 		return(False);	dgram->datasize = length-offset;	memcpy(dgram->data,inbuf+offset,dgram->datasize);	/* Paranioa. Ensure the last 2 bytes in the dgram buffer are	   zero. This should be true anyway, just enforce it for paranioa sake. JRA. */	SMB_ASSERT(dgram->datasize <= (sizeof(dgram->data)-2));	memset(&dgram->data[sizeof(dgram->data)-2], '\0', 2);	return(True);}/******************************************************************* Parse a nmb packet. Return False if the packet can't be parsed  or is invalid for some reason, True otherwise.******************************************************************/static BOOL parse_nmb(char *inbuf,int length,struct nmb_packet *nmb){	int nm_flags,offset;	memset((char *)nmb,'\0',sizeof(*nmb));	if (length < 12)		return(False);	/* parse the header */	nmb->header.name_trn_id = RSVAL(inbuf,0);	DEBUG(10,("parse_nmb: packet id = %d\n", nmb->header.name_trn_id));	nmb->header.opcode = (CVAL(inbuf,2) >> 3) & 0xF;	nmb->header.response = ((CVAL(inbuf,2)>>7)&1)?True:False;	nm_flags = ((CVAL(inbuf,2) & 0x7) << 4) + (CVAL(inbuf,3)>>4);	nmb->header.nm_flags.bcast = (nm_flags&1)?True:False;	nmb->header.nm_flags.recursion_available = (nm_flags&8)?True:False;	nmb->header.nm_flags.recursion_desired = (nm_flags&0x10)?True:False;	nmb->header.nm_flags.trunc = (nm_flags&0x20)?True:False;	nmb->header.nm_flags.authoritative = (nm_flags&0x40)?True:False;  	nmb->header.rcode = CVAL(inbuf,3) & 0xF;	nmb->header.qdcount = RSVAL(inbuf,4);	nmb->header.ancount = RSVAL(inbuf,6);	nmb->header.nscount = RSVAL(inbuf,8);	nmb->header.arcount = RSVAL(inbuf,10);  	if (nmb->header.qdcount) {		offset = parse_nmb_name(inbuf,12,length,&nmb->question.question_name);		if (!offset)			return(False);		if (length - (12+offset) < 4)			return(False);		nmb->question.question_type = RSVAL(inbuf,12+offset);		nmb->question.question_class = RSVAL(inbuf,12+offset+2);		offset += 12+4;	} else {		offset = 12;	}	/* and any resource records */	if (nmb->header.ancount && !parse_alloc_res_rec(inbuf,&offset,length,&nmb->answers,					nmb->header.ancount))		return(False);	if (nmb->header.nscount && !parse_alloc_res_rec(inbuf,&offset,length,&nmb->nsrecs,					nmb->header.nscount))		return(False);  	if (nmb->header.arcount && !parse_alloc_res_rec(inbuf,&offset,length,&nmb->additional,					nmb->header.arcount))		return(False);	return(True);}/******************************************************************* 'Copy constructor' for an nmb packet.******************************************************************/static struct packet_struct *copy_nmb_packet(struct packet_struct *packet){  	struct nmb_packet *nmb;	struct nmb_packet *copy_nmb;	struct packet_struct *pkt_copy;	if(( pkt_copy = SMB_MALLOC_P(struct packet_struct)) == NULL) {		DEBUG(0,("copy_nmb_packet: malloc fail.\n"));		return NULL;	}	/* Structure copy of entire thing. */	*pkt_copy = *packet;	/* Ensure this copy is not locked. */	pkt_copy->locked = False;	/* Ensure this copy has no resource records. */	nmb = &packet->packet.nmb;	copy_nmb = &pkt_copy->packet.nmb;	copy_nmb->answers = NULL;	copy_nmb->nsrecs = NULL;	copy_nmb->additional = NULL;	/* Now copy any resource records. */	if (nmb->answers) {		if((copy_nmb->answers = SMB_MALLOC_ARRAY(struct res_rec,nmb->header.ancount)) == NULL)			goto free_and_exit;		memcpy((char *)copy_nmb->answers, (char *)nmb->answers, 				nmb->header.ancount * sizeof(struct res_rec));	}	if (nmb->nsrecs) {		if((copy_nmb->nsrecs = SMB_MALLOC_ARRAY(struct res_rec, nmb->header.nscount)) == NULL)			goto free_and_exit;		memcpy((char *)copy_nmb->nsrecs, (char *)nmb->nsrecs, 				nmb->header.nscount * sizeof(struct res_rec));	}	if (nmb->additional) {		if((copy_nmb->additional = SMB_MALLOC_ARRAY(struct res_rec, nmb->header.arcount)) == NULL)			goto free_and_exit;		memcpy((char *)copy_nmb->additional, (char *)nmb->additional, 				nmb->header.arcount * sizeof(struct res_rec));	}	return pkt_copy; free_and_exit:	SAFE_FREE(copy_nmb->answers);	SAFE_FREE(copy_nmb->nsrecs);	SAFE_FREE(copy_nmb->additional);	SAFE_FREE(pkt_copy);	DEBUG(0,("copy_nmb_packet: malloc fail in resource records.\n"));	return NULL;}/*******************************************************************  'Copy constructor' for a dgram packet.******************************************************************/static struct packet_struct *copy_dgram_packet(struct packet_struct *packet){ 	struct packet_struct *pkt_copy;	if(( pkt_copy = SMB_MALLOC_P(struct packet_struct)) == NULL) {		DEBUG(0,("copy_dgram_packet: malloc fail.\n"));		return NULL;	}	/* Structure copy of entire thing. */	*pkt_copy = *packet;	/* Ensure this copy is not locked. */	pkt_copy->locked = False;	/* There are no additional pointers in a dgram packet,		we are finished. */	return pkt_copy;}/******************************************************************* 'Copy constructor' for a generic packet.******************************************************************/struct packet_struct *copy_packet(struct packet_struct *packet){  	if(packet->packet_type == NMB_PACKET)		return copy_nmb_packet(packet);	else if (packet->packet_type == DGRAM_PACKET)		return copy_dgram_packet(packet);	return NULL;} /******************************************************************* Free up any resources associated with an nmb packet.******************************************************************/static void free_nmb_packet(struct nmb_packet *nmb){  	SAFE_FREE(nmb->answers);	SAFE_FREE(nmb->nsrecs);	SAFE_FREE(nmb->additional);}/******************************************************************* Free up any resources associated with a dgram packet.******************************************************************/static void free_dgram_packet(struct dgram_packet *nmb){  	/* We have nothing to do for a dgram packet. */}/******************************************************************* Free up any resources associated with a packet.******************************************************************/void free_packet(struct packet_struct *packet){  	if (packet->locked) 		return;	if (packet->packet_type == NMB_PACKET)		free_nmb_packet(&packet->packet.nmb);	else if (packet->packet_type == DGRAM_PACKET)		free_dgram_packet(&packet->packet.dgram);	ZERO_STRUCTPN(packet);	SAFE_FREE(packet);}/******************************************************************* Parse a packet buffer into a packet structure.******************************************************************/struct packet_struct *parse_packet(char *buf,int length,				   enum packet_type packet_type){	struct packet_struct *p;	BOOL ok=False;	p = SMB_MALLOC_P(struct packet_struct);	if (!p)		return(NULL);	p->next = NULL;	p->prev = NULL;	p->ip = lastip;	p->port = lastport;	p->locked = False;	p->timestamp = time(NULL);	p->packet_type = packet_type;	switch (packet_type) {	case NMB_PACKET:		ok = parse_nmb(buf,length,&p->packet.nmb);		break;			case DGRAM_PACKET:		ok = parse_dgram(buf,length,&p->packet.dgram);		break;	}	if (!ok) {		free_packet(p);		return NULL;	}	return p;}/******************************************************************* Read a packet from a socket and parse it, returning a packet ready to be used or put on the queue. This assumes a UDP socket.******************************************************************/struct packet_struct *read_packet(int fd,enum packet_type packet_type){	struct packet_struct *packet;	char buf[MAX_DGRAM_SIZE];	int length;		length = read_udp_socket(fd,buf,sizeof(buf));	if (length < MIN_DGRAM_SIZE)		return(NULL);		packet = parse_packet(buf, length, packet_type);	if (!packet)		return NULL;	packet->fd = fd;		num_good_receives++;		DEBUG(5,("Received a packet of len %d from (%s) port %d\n",		 length, inet_ntoa(packet->ip), packet->port ) );		return(packet);}					 /******************************************************************* Send a udp packet on a already open socket.******************************************************************/static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port){	BOOL ret = False;	int i;	struct sockaddr_in sock_out;	/* set the address and port */	memset((char *)&sock_out,'\0',sizeof(sock_out));	putip((char *)&sock_out.sin_addr,(char *)&ip);	sock_out.sin_port = htons( port );	sock_out.sin_family = AF_INET;  	DEBUG( 5, ( "Sending a packet of len %d to (%s) on port %d\n",			len, inet_ntoa(ip), port ) );	/*	 * Patch to fix asynch error notifications from Linux kernel.	 */		for (i = 0; i < 5; i++) {		ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out, sizeof(sock_out)) >= 0);		if (ret || errno != ECONNREFUSED)			break;	}	if (!ret)		DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n",			inet_ntoa(ip),port,strerror(errno)));	if (ret)		num_good_sends++;	return(ret);}/******************************************************************* Build a dgram packet ready for sending. XXXX This currently doesn't handle packets too big for one datagram. It should split them and use the packet_offset, more and first flags to handle the fragmentation. Yuck.   [...but it isn't clear that we would ever need to send a   a fragmented NBT Datagram.  The IP layer does its own   fragmentation to ensure that messages can fit into the path   MTU.  It *is* important to be able to receive and rebuild   fragmented NBT datagrams, just in case someone out there   really has implemented this 'feature'.  crh -)------ ]******************************************************************/static int build_dgram(char *buf,struct packet_struct *p){	struct dgram_packet *dgram = &p->packet.dgram;	unsigned char *ubuf = (unsigned char *)buf;	int offset=0;	/* put in the header */	ubuf[0] = dgram->header.msg_type;	ubuf[1] = (((int)dgram->header.flags.node_type)<<2);	if (dgram->header.flags.more)		ubuf[1] |= 1;	if (dgram->header.flags.first)		ubuf[1] |= 2;	RSSVAL(ubuf,2,dgram->header.dgm_id);	putip(ubuf+4,(char *)&dgram->header.source_ip);	RSSVAL(ubuf,8,dgram->header.source_port);	RSSVAL(ubuf,12,dgram->header.packet_offset);	offset = 14;	if (dgram->header.msg_type == 0x10 ||			dgram->header.msg_type == 0x11 ||			dgram->header.msg_type == 0x12) {      		offset += put_nmb_name((char *)ubuf,offset,&dgram->source_name);		offset += put_nmb_name((char *)ubuf,offset,&dgram->dest_name);	}	memcpy(ubuf+offset,dgram->data,dgram->datasize);	offset += dgram->datasize;	/* automatically set the dgm_length	 * NOTE: RFC1002 says the dgm_length does *not*	 *       include the fourteen-byte header. crh	 */	dgram->header.dgm_length = (offset - 14);	RSSVAL(ubuf,10,dgram->header.dgm_length); 	return(offset);}/******************************************************************* Build a nmb name*******************************************************************/void make_nmb_name( struct nmb_name *n, const char *name, int type){	fstring unix_name;	memset( (char *)n, '\0', sizeof(struct nmb_name) );	fstrcpy(unix_name, name);	strupper_m(unix_name);	push_ascii(n->name, unix_name, sizeof(n->name), STR_TERMINATE);	n->name_type = (unsigned int)type & 0xFF;	push_ascii(n->scope,  global_scope(), 64, STR_TERMINATE);}/*******************************************************************  Compare two nmb names******************************************************************/BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2){	return ((n1->name_type == n2->name_type) &&		strequal(n1->name ,n2->name ) &&		strequal(n1->scope,n2->scope));}/******************************************************************* Build a nmb packet ready for sending. XXXX this currently relies on not being passed something that expands to a packet too big for the buffer. Eventually this should be changed to set the trunc bit so the receiver can request the rest via tcp (when that becomes supported)******************************************************************/static int build_nmb(char *buf,struct packet_struct *p){	struct nmb_packet *nmb = &p->packet.nmb;	unsigned char *ubuf = (unsigned char *)buf;	int offset=0;	/* put in the header */

⌨️ 快捷键说明

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