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

📄 nmbd_nameregister.c

📁 samba-3.0.22.tar.gz 编译smb服务器的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    Unix SMB/CIFS implementation.   NBT netbios routines and daemon - version 2   Copyright (C) Andrew Tridgell 1994-1998   Copyright (C) Luke Kenneth Casson Leighton 1994-1998   Copyright (C) Jeremy Allison 1994-2003      This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 2 of the License, or   (at your option) any later version.      This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.      You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.   */#include "includes.h"/* forward declarations */static void wins_next_registration(struct response_record *rrec);/**************************************************************************** Deal with a response packet when registering one of our names.****************************************************************************/static void register_name_response(struct subnet_record *subrec,                       struct response_record *rrec, struct packet_struct *p){	/* 	 * If we are registering broadcast, then getting a response is an	 * error - we do not have the name. If we are registering unicast,	 * then we expect to get a response.	 */	struct nmb_packet *nmb = &p->packet.nmb;	BOOL bcast = nmb->header.nm_flags.bcast;	BOOL success = True;	struct nmb_name *question_name = &rrec->packet->packet.nmb.question.question_name;	struct nmb_name *answer_name = &nmb->answers->rr_name;	struct nmb_packet *sent_nmb = &rrec->packet->packet.nmb;	int ttl = 0;	uint16 nb_flags = 0;	struct in_addr register_ip;	fstring reg_name;		putip(&register_ip,&sent_nmb->additional->rdata[2]);	fstrcpy(reg_name, inet_ntoa(register_ip));		if (subrec == unicast_subnet) {		/* we know that this wins server is definately alive - for the moment! */		wins_srv_alive(rrec->packet->ip, register_ip);	}	/* Sanity check. Ensure that the answer name in the incoming packet is the	   same as the requested name in the outgoing packet. */	if(!question_name || !answer_name) {		DEBUG(0,("register_name_response: malformed response (%s is NULL).\n",			 question_name ? "question_name" : "answer_name" ));		return;	}	if(!nmb_name_equal(question_name, answer_name)) {		DEBUG(0,("register_name_response: Answer name %s differs from question name %s.\n", 			 nmb_namestr(answer_name), nmb_namestr(question_name)));		return;	}	if(bcast) {		/*		 * Special hack to cope with old Samba nmbd's.		 * Earlier versions of Samba (up to 1.9.16p11) respond 		 * to a broadcast name registration of WORKGROUP<1b> when 		 * they should not. Hence, until these versions are gone, 		 * we should treat such errors as success for this particular		 * case only. jallison@whistle.com.		 */		#if 1 /* OLD_SAMBA_SERVER_HACK */		unstring ans_name;		pull_ascii_nstring(ans_name, sizeof(ans_name), answer_name->name);		if((nmb->header.rcode == ACT_ERR) && strequal(lp_workgroup(), ans_name) &&		   (answer_name->name_type == 0x1b)) {			/* Pretend we did not get this. */			rrec->num_msgs--;			DEBUG(5,("register_name_response: Ignoring broadcast response to registration of name %s due to old Samba server bug.\n", 				 nmb_namestr(answer_name)));			return;		}#endif /* OLD_SAMBA_SERVER_HACK */		/* Someone else has the name. Log the problem. */		DEBUG(1,("register_name_response: Failed to register name %s IP %s on subnet %s via broadcast. Error code was %d. Reject came from IP %s\n", 			 nmb_namestr(answer_name), 			 reg_name,			 subrec->subnet_name, nmb->header.rcode, inet_ntoa(p->ip)));		success = False;	} else {		/* Unicast - check to see if the response allows us to have the name. */		if (nmb->header.opcode == NMB_WACK_OPCODE) {			/* WINS server is telling us to wait. Pretend we didn't get			   the response but don't send out any more register requests. */			DEBUG(5,("register_name_response: WACK from WINS server %s in registering name %s IP %s\n", 				 inet_ntoa(p->ip), nmb_namestr(answer_name), reg_name));			rrec->repeat_count = 0;			/* How long we should wait for. */			rrec->repeat_time = p->timestamp + nmb->answers->ttl;			rrec->num_msgs--;			return;		} else if (nmb->header.rcode != 0) {			/* Error code - we didn't get the name. */			success = False;			DEBUG(0,("register_name_response: %sserver at IP %s rejected our name registration of %s IP %s with error code %d.\n", 				 subrec==unicast_subnet?"WINS ":"",				 inet_ntoa(p->ip), 				 nmb_namestr(answer_name), 				 reg_name,				 nmb->header.rcode));		} else {			success = True;			/* Get the data we need to pass to the success function. */			nb_flags = get_nb_flags(nmb->answers->rdata);			ttl = nmb->answers->ttl;			/* send off a registration for the next IP, if any */			wins_next_registration(rrec);		}	} 	DEBUG(5,("register_name_response: %s in registering %sname %s IP %s with %s.\n",		 success ? "success" : "failure", 		 subrec==unicast_subnet?"WINS ":"",		 nmb_namestr(answer_name), 		 reg_name,		 inet_ntoa(rrec->packet->ip)));	if(success) {		/* Enter the registered name into the subnet name database before calling		   the success function. */		standard_success_register(subrec, rrec->userdata, answer_name, nb_flags, ttl, register_ip);		if( rrec->success_fn)			(*(register_name_success_function)rrec->success_fn)(subrec, rrec->userdata, answer_name, nb_flags, ttl, register_ip);	} else {		if( rrec->fail_fn)			(*(register_name_fail_function)rrec->fail_fn)(subrec, rrec, question_name);		/* Remove the name. */		standard_fail_register( subrec, rrec, question_name);	}	/* Ensure we don't retry. */	remove_response_record(subrec, rrec);}/**************************************************************************** Deal with a timeout of a WINS registration request****************************************************************************/static void wins_registration_timeout(struct subnet_record *subrec,				      struct response_record *rrec){	struct userdata_struct *userdata = rrec->userdata;	struct nmb_packet *sent_nmb = &rrec->packet->packet.nmb;	struct nmb_name *nmbname = &sent_nmb->question.question_name;	struct in_addr register_ip;	fstring src_addr;	putip(&register_ip,&sent_nmb->additional->rdata[2]);	fstrcpy(src_addr, inet_ntoa(register_ip));	DEBUG(2,("wins_registration_timeout: WINS server %s timed out registering IP %s\n", 		 inet_ntoa(rrec->packet->ip), src_addr));	/* mark it temporarily dead for this source address */	wins_srv_died(rrec->packet->ip, register_ip);	/* if we have some userdata then use that to work out what	   wins server to try next */	if (userdata) {		const char *tag = (const char *)userdata->data;		/* try the next wins server in our failover list for		   this tag */		rrec->packet->ip = wins_srv_ip_tag(tag, register_ip);	}	/* if we have run out of wins servers for this tag then they	   must all have timed out. We treat this as *success*, not	   failure, and go into our standard name refresh mode. This	   copes with all the wins servers being down */	if (wins_srv_is_dead(rrec->packet->ip, register_ip)) {		uint16 nb_flags = get_nb_flags(sent_nmb->additional->rdata);		int ttl = sent_nmb->additional->ttl;		standard_success_register(subrec, userdata, nmbname, nb_flags, ttl, register_ip);		if(rrec->success_fn) {			(*(register_name_success_function)rrec->success_fn)(subrec, 									    rrec->userdata, 									    nmbname, 									    nb_flags, 									    ttl, 									    register_ip);		}		/* send off a registration for the next IP, if any */		wins_next_registration(rrec);		/* don't need to send this packet any more */		remove_response_record(subrec, rrec);		return;	}		/* we will be moving to the next WINS server for this group,	   send it immediately */	rrec->repeat_count = 2;	rrec->repeat_time = time(NULL) + 1;	rrec->in_expiration_processing = False;	DEBUG(6,("Retrying register of name %s IP %s with WINS server %s\n",		 nmb_namestr(nmbname), src_addr, inet_ntoa(rrec->packet->ip)));	/* notice that we don't remove the response record. This keeps	   us trying to register with each of our failover wins servers */}/**************************************************************************** Deal with a timeout when registering one of our names.****************************************************************************/static void register_name_timeout_response(struct subnet_record *subrec,					   struct response_record *rrec){	/*	 * If we are registering unicast, then NOT getting a response is an	 * error - we do not have the name. If we are registering broadcast,	 * then we don't expect to get a response.	 */	struct nmb_packet *sent_nmb = &rrec->packet->packet.nmb;	BOOL bcast = sent_nmb->header.nm_flags.bcast;	BOOL success = False;	struct nmb_name *question_name = &sent_nmb->question.question_name;	uint16 nb_flags = 0;	int ttl = 0;	struct in_addr registered_ip;		if (bcast) {		if(rrec->num_msgs == 0) {			/* Not receiving a message is success for broadcast registration. */			success = True; 			/* Pull the success values from the original request packet. */			nb_flags = get_nb_flags(sent_nmb->additional->rdata);			ttl = sent_nmb->additional->ttl;			putip(&registered_ip,&sent_nmb->additional->rdata[2]);		}	} else {

⌨️ 快捷键说明

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