void process_workgroup_announce(struct subnet_record *subrec, struct packet_struct *p, char *buf)
{
	struct dgram_packet *dgram = &p->packet.dgram;
	int ttl = IVAL(buf,1)/1000;
	unstring workgroup_announce_name;
	unstring master_name;
	uint32 servertype = IVAL(buf,23);
	struct work_record *work;
	unstring source_name;
	unstring dest_name;

	START_PROFILE(workgroup_announce);

	pull_ascii_nstring(workgroup_announce_name,sizeof(workgroup_announce_name),buf+5);
	pull_ascii_nstring(master_name,sizeof(master_name),buf+31);
	pull_ascii_nstring(source_name,sizeof(source_name),dgram->source_name.name);
	pull_ascii_nstring(dest_name,sizeof(dest_name),dgram->dest_name.name);

	DEBUG(3,("process_workgroup_announce: from %s<%02x> IP %s to \
%s for workgroup %s.\n", source_name, source_name[15], inet_ntoa(p->ip),
			nmb_namestr(&dgram->dest_name),workgroup_announce_name));

	DEBUG(5,("process_workgroup_announce: ttl=%d server type=%08x master browser=%s\n",
		ttl, servertype, master_name));

	/* Workgroup announcements must only go to the MSBROWSE name. */
	if (!strequal(dest_name, MSBROWSE) || (dgram->dest_name.name_type != 0x1)) {
		DEBUG(0,("process_workgroup_announce: from IP %s should be to __MSBROWSE__<0x01> not %s\n",
			inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
		goto done;
	}

	if ((work = find_workgroup_on_subnet(subrec, workgroup_announce_name))==NULL) {
		/* We have no record of this workgroup. Add it. */
		if((work = create_workgroup_on_subnet(subrec, workgroup_announce_name, ttl))==NULL)
			goto done;
	} else {
		/* Update the workgroup death_time. */
		update_workgroup_ttl(work, ttl);
	}

	if(*work->local_master_browser_name == '\0') {
		/* Set the master browser name. */
		set_workgroup_local_master_browser_name( work, master_name );
	}

	subrec->work_changed = True;

done:

	END_PROFILE(workgroup_announce);
}
예제 #2
0
static void complete_one(struct sync_record *s,
			 char *sname, uint32 stype, char *comment)
{
	struct work_record *work;
	struct server_record *servrec;

	stype &= ~SV_TYPE_LOCAL_LIST_ONLY;

	if (stype & SV_TYPE_DOMAIN_ENUM) {
		/* See if we can find the workgroup on this subnet. */
		if((work=find_workgroup_on_subnet(unicast_subnet, sname))) {
			/* We already know about this workgroup -
                           update the ttl. */
			update_workgroup_ttl(work,lp_max_ttl());
		} else {
			/* Create the workgroup on the subnet. */
			work = create_workgroup_on_subnet(unicast_subnet, 
							  sname, lp_max_ttl());
			if (work) {
				/* remember who the master is */
				unstrcpy(work->local_master_browser_name, comment);
			}
		}
		return;
	} 

	work = find_workgroup_on_subnet(unicast_subnet, s->workgroup);
	if (!work) {
		DEBUG(3,("workgroup %s doesn't exist on unicast subnet?\n",
			 s->workgroup));
		return;
	}

	if ((servrec = find_server_in_workgroup( work, sname))) {
		/* Check that this is not a locally known
		   server - if so ignore the entry. */
		if(!(servrec->serv.type & SV_TYPE_LOCAL_LIST_ONLY)) {
			/* We already know about this server - update
                           the ttl. */
			update_server_ttl(servrec, lp_max_ttl());
			/* Update the type. */
			servrec->serv.type = stype;
		}
		return;
	} 

	/* Create the server in the workgroup. */ 
	create_server_on_workgroup(work, sname,stype, lp_max_ttl(), comment);
}