📄 nmbd_sendannounce.c
字号:
/* 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-1998 SMB Version handling Copyright (C) John H Terpstra 1995-1998 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"extern int updatecount;extern BOOL found_lm_clients;/**************************************************************************** Send a browser reset packet.**************************************************************************/void send_browser_reset(int reset_type, const char *to_name, int to_type, struct in_addr to_ip){ pstring outbuf; char *p; DEBUG(3,("send_browser_reset: sending reset request type %d to %s<%02x> IP %s.\n", reset_type, to_name, to_type, inet_ntoa(to_ip) )); memset(outbuf,'\0',sizeof(outbuf)); p = outbuf; SCVAL(p,0,ANN_ResetBrowserState); p++; SCVAL(p,0,reset_type); p++; send_mailslot(True, BROWSE_MAILSLOT, outbuf,PTR_DIFF(p,outbuf), global_myname(), 0x0, to_name, to_type, to_ip, FIRST_SUBNET->myip, DGRAM_PORT);}/**************************************************************************** Broadcast a packet to the local net requesting that all servers in this workgroup announce themselves to us. **************************************************************************/void broadcast_announce_request(struct subnet_record *subrec, struct work_record *work){ pstring outbuf; char *p; work->needannounce = True; DEBUG(3,("broadcast_announce_request: sending announce request for workgroup %s \to subnet %s\n", work->work_group, subrec->subnet_name)); memset(outbuf,'\0',sizeof(outbuf)); p = outbuf; SCVAL(p,0,ANN_AnnouncementRequest); p++; SCVAL(p,0,work->token); /* (local) Unique workgroup token id. */ p++; p += push_string(NULL, p+1, global_myname(), 15, STR_ASCII|STR_UPPER|STR_TERMINATE); send_mailslot(False, BROWSE_MAILSLOT, outbuf,PTR_DIFF(p,outbuf), global_myname(), 0x0, work->work_group,0x1e, subrec->bcast_ip, subrec->myip, DGRAM_PORT);}/**************************************************************************** Broadcast an announcement. **************************************************************************/static void send_announcement(struct subnet_record *subrec, int announce_type, const char *from_name, const char *to_name, int to_type, struct in_addr to_ip, time_t announce_interval, const char *server_name, int server_type, const char *server_comment){ pstring outbuf; unstring upper_server_name; char *p; memset(outbuf,'\0',sizeof(outbuf)); p = outbuf+1; SCVAL(outbuf,0,announce_type); /* Announcement parameters. */ SCVAL(p,0,updatecount); SIVAL(p,1,announce_interval*1000); /* Milliseconds - despite the spec. */ safe_strcpy(upper_server_name, server_name, sizeof(upper_server_name)-1); strupper_m(upper_server_name); push_string(NULL, p+5, upper_server_name, 16, STR_ASCII|STR_TERMINATE); SCVAL(p,21,lp_major_announce_version()); /* Major version. */ SCVAL(p,22,lp_minor_announce_version()); /* Minor version. */ SIVAL(p,23,server_type & ~SV_TYPE_LOCAL_LIST_ONLY); /* Browse version: got from NT/AS 4.00 - Value defined in smb.h (JHT). */ SSVAL(p,27,BROWSER_ELECTION_VERSION); SSVAL(p,29,BROWSER_CONSTANT); /* Browse signature. */ p += 31 + push_string(NULL, p+31, server_comment, -1, STR_ASCII|STR_TERMINATE); send_mailslot(False,BROWSE_MAILSLOT, outbuf, PTR_DIFF(p,outbuf), from_name, 0x0, to_name, to_type, to_ip, subrec->myip, DGRAM_PORT);}/**************************************************************************** Broadcast a LanMan announcement.**************************************************************************/static void send_lm_announcement(struct subnet_record *subrec, int announce_type, char *from_name, char *to_name, int to_type, struct in_addr to_ip, time_t announce_interval, char *server_name, int server_type, char *server_comment){ pstring outbuf; char *p=outbuf; memset(outbuf,'\0',sizeof(outbuf)); SSVAL(p,0,announce_type); SIVAL(p,2,server_type & ~SV_TYPE_LOCAL_LIST_ONLY); SCVAL(p,6,lp_major_announce_version()); /* Major version. */ SCVAL(p,7,lp_minor_announce_version()); /* Minor version. */ SSVAL(p,8,announce_interval); /* In seconds - according to spec. */ p += 10; p += push_string(NULL, p, server_name, 15, STR_ASCII|STR_UPPER|STR_TERMINATE); p += push_string(NULL, p, server_comment, sizeof(pstring)-15, STR_ASCII|STR_UPPER|STR_TERMINATE); send_mailslot(False,LANMAN_MAILSLOT, outbuf, PTR_DIFF(p,outbuf), from_name, 0x0, to_name, to_type, to_ip, subrec->myip, DGRAM_PORT);}/**************************************************************************** We are a local master browser. Announce this to WORKGROUP<1e>.****************************************************************************/static void send_local_master_announcement(struct subnet_record *subrec, struct work_record *work, struct server_record *servrec){ /* Ensure we don't have the prohibited bit set. */ uint32 type = servrec->serv.type & ~SV_TYPE_LOCAL_LIST_ONLY; DEBUG(3,("send_local_master_announcement: type %x for name %s on subnet %s for workgroup %s\n", type, global_myname(), subrec->subnet_name, work->work_group)); send_announcement(subrec, ANN_LocalMasterAnnouncement, global_myname(), /* From nbt name. */ work->work_group, 0x1e, /* To nbt name. */ subrec->bcast_ip, /* To ip. */ work->announce_interval, /* Time until next announce. */ global_myname(), /* Name to announce. */ type, /* Type field. */ servrec->serv.comment);}/**************************************************************************** Announce the workgroup WORKGROUP to MSBROWSE<01>.****************************************************************************/static void send_workgroup_announcement(struct subnet_record *subrec, struct work_record *work){ DEBUG(3,("send_workgroup_announcement: on subnet %s for workgroup %s\n", subrec->subnet_name, work->work_group)); send_announcement(subrec, ANN_DomainAnnouncement, global_myname(), /* From nbt name. */ MSBROWSE, 0x1, /* To nbt name. */ subrec->bcast_ip, /* To ip. */ work->announce_interval, /* Time until next announce. */ work->work_group, /* Name to announce. */ SV_TYPE_DOMAIN_ENUM|SV_TYPE_NT, /* workgroup announce flags. */ global_myname()); /* From name as comment. */}/**************************************************************************** Announce the given host to WORKGROUP<1d>.****************************************************************************/static void send_host_announcement(struct subnet_record *subrec, struct work_record *work, struct server_record *servrec){ /* Ensure we don't have the prohibited bits set. */ uint32 type = servrec->serv.type & ~SV_TYPE_LOCAL_LIST_ONLY; DEBUG(3,("send_host_announcement: type %x for host %s on subnet %s for workgroup %s\n", type, servrec->serv.name, subrec->subnet_name, work->work_group)); send_announcement(subrec, ANN_HostAnnouncement, servrec->serv.name, /* From nbt name. */ work->work_group, 0x1d, /* To nbt name. */ subrec->bcast_ip, /* To ip. */ work->announce_interval, /* Time until next announce. */ servrec->serv.name, /* Name to announce. */ type, /* Type field. */ servrec->serv.comment);}/**************************************************************************** Announce the given LanMan host****************************************************************************/static void send_lm_host_announcement(struct subnet_record *subrec, struct work_record *work, struct server_record *servrec, int lm_interval){ /* Ensure we don't have the prohibited bits set. */ uint32 type = servrec->serv.type & ~SV_TYPE_LOCAL_LIST_ONLY; DEBUG(3,("send_lm_host_announcement: type %x for host %s on subnet %s for workgroup %s, ttl: %d\n", type, servrec->serv.name, subrec->subnet_name, work->work_group, lm_interval)); send_lm_announcement(subrec, ANN_HostAnnouncement, servrec->serv.name, /* From nbt name. */ work->work_group, 0x00, /* To nbt name. */ subrec->bcast_ip, /* To ip. */ lm_interval, /* Time until next announce. */ servrec->serv.name, /* Name to announce (fstring not netbios name struct). */ type, /* Type field. */ servrec->serv.comment);}/**************************************************************************** Announce a server record. ****************************************************************************/static void announce_server(struct subnet_record *subrec, struct work_record *work, struct server_record *servrec){ /* Only do domain announcements if we are a master and it's our primary name we're being asked to announce. */ if (AM_LOCAL_MASTER_BROWSER(work) && strequal(global_myname(),servrec->serv.name)) { send_local_master_announcement(subrec, work, servrec); send_workgroup_announcement(subrec, work); } else { send_host_announcement(subrec, work, servrec); }}/**************************************************************************** Go through all my registered names on all broadcast subnets and announce them if the timeout requires it. **************************************************************************/void announce_my_server_names(time_t t){ struct subnet_record *subrec; for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) { struct work_record *work = find_workgroup_on_subnet(subrec, lp_workgroup()); if(work) { struct server_record *servrec; if (work->needannounce) { /* Drop back to a max 3 minute announce. This is to prevent a single lost packet from breaking things for too long. */ work->announce_interval = MIN(work->announce_interval, CHECK_TIME_MIN_HOST_ANNCE*60); work->lastannounce_time = t - (work->announce_interval+1); work->needannounce = False; } /* Announce every minute at first then progress to every 12 mins */ if ((t - work->lastannounce_time) < work->announce_interval) continue; if (work->announce_interval < (CHECK_TIME_MAX_HOST_ANNCE * 60)) work->announce_interval += 60;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -