This commit was manufactured by cvs2svn to create tag
[Samba.git] / source / nameresp.c
blobde1f33c7172100017b989f8807ccf44b55ca9c91
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
4 NBT netbios library routines
5 Copyright (C) Andrew Tridgell 1994-1997
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 Module name: nameresp.c
25 #include "includes.h"
27 extern int ClientNMB;
29 extern struct subnet_record *subnetlist;
31 extern int DEBUGLEVEL;
33 extern pstring scope;
34 extern struct in_addr ipzero;
35 extern struct in_addr wins_ip;
38 /***************************************************************************
39 deals with an entry before it dies
40 **************************************************************************/
41 static void dead_netbios_entry(struct subnet_record *d,
42 struct response_record *n)
44 DEBUG(3,("Removing dead netbios entry for %s %s (num_msgs=%d)\n",
45 inet_ntoa(n->send_ip), namestr(&n->name), n->num_msgs));
47 debug_state_type(n->state);
49 switch (n->state)
51 case NAME_QUERY_CONFIRM:
53 if (!lp_wins_support()) return; /* only if we're a WINS server */
55 if (n->num_msgs == 0)
57 /* oops. name query had no response. check that the name is
58 unique and then remove it from our WINS database */
60 /* IMPORTANT: see query_refresh_names() */
62 if ((!NAME_GROUP(n->nb_flags)))
64 struct subnet_record *d1 = wins_client_subnet;
65 if (d1)
67 /* remove the name that had been registered with us,
68 and we're now getting no response when challenging.
69 see rfc1001.txt 15.5.2
71 remove_netbios_name(d1, n->name.name, n->name.name_type, REGISTER);
75 break;
78 case NAME_QUERY_MST_CHK:
80 /* if no response received, the master browser must have gone
81 down on that subnet, without telling anyone. */
83 /* IMPORTANT: see response_netbios_packet() */
85 if (n->num_msgs == 0)
86 browser_gone(n->name.name, n->send_ip);
87 break;
90 case NAME_RELEASE:
92 /* if no response received, it must be OK for us to release the
93 name. nobody objected (including a potentially dead or deaf
94 WINS server) */
96 /* IMPORTANT: see response_name_release() */
98 if (ismyip(n->send_ip))
100 name_unregister_work(d,n->name.name,n->name.name_type);
102 if (!n->bcast && n->num_msgs == 0)
104 DEBUG(0,("WINS server did not respond to name release!\n"));
105 /* XXXX whoops. we have problems. must deal with this */
107 break;
110 case NAME_REGISTER_CHALLENGE:
112 /* name challenge: no reply. we can reply to the person that
113 wanted the unique name and tell them that they can have it
116 add_name_respond(d,n->fd,d->myip, n->reply_id ,&n->name,
117 n->nb_flags, GET_TTL(0),
118 n->reply_to_ip, True, n->reply_to_ip);
119 break;
122 case NAME_REGISTER:
124 /* if no response received, and we are using a broadcast registration
125 method, it must be OK for us to register the name: nobody objected
126 on that subnet. if we are using a WINS server, then the WINS
127 server must be dead or deaf.
129 if (n->num_msgs == 0)
131 if (n->bcast)
133 /* broadcast method: implicit acceptance of the name registration
134 by not receiving any objections. */
136 /* IMPORTANT: see response_name_reg() */
138 name_register_work(d,n->name.name,n->name.name_type,
139 n->nb_flags, n->ttl, n->reply_to_ip, n->bcast);
141 else
143 /* received no response. rfc1001.txt states that after retrying,
144 we should assume the WINS server is dead, and fall back to
145 broadcasting (see bits about M nodes: can't find any right
146 now) */
148 DEBUG(1,("WINS server did not respond to name registration!\n"));
149 /* XXXX whoops. we have problems. must deal with this */
152 break;
155 case NAME_QUERY_DOMAIN:
157 /* if no response was received, there is no domain controller for
158 this DOMAIN registered within WINS. it's ok for us to register
159 the DOMAIN<1b> name.
162 if (n->num_msgs == 0)
164 struct work_record *work = find_workgroupstruct(d,n->name.name,False);
165 if (work && d)
167 become_domain_master(d,work);
170 else
172 DEBUG(1, ("nmbd configured as domain master and one already exists\n"));
174 break;
177 default:
179 /* nothing to do but delete the dead expected-response structure */
180 /* this is normal. */
181 break;
187 /*******************************************************************
188 remove old name response entries
190 XXXX retry code needs to be added, including a retry wait period and a count
191 see name_query() and name_status() for suggested implementation.
193 ******************************************************************/
194 void expire_netbios_response_entries(time_t t)
196 struct subnet_record *d;
198 for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_INCLUDING_WINS(d))
200 struct response_record *n, *nextn;
202 for (n = d->responselist; n; n = nextn)
204 nextn = n->next;
206 if (n->repeat_time <= t)
208 if (n->repeat_count > 0)
210 /* resend the entry */
211 initiate_netbios_packet(&n->response_id, n->fd, n->quest_type,
212 n->name.name, n->name.name_type,
213 n->nb_flags, n->bcast, n->recurse, n->send_ip);
215 n->repeat_time += n->repeat_interval; /* XXXX ms needed */
216 n->repeat_count--;
219 else
221 DEBUG(4,("timeout response %d for %s %s\n",
222 n->response_id, namestr(&n->name),
223 inet_ntoa(n->send_ip)));
225 dead_netbios_entry(d,n); /* process the non-response */
226 remove_response_record(d,n); /* remove the non-response */
228 continue;
236 /****************************************************************************
237 wrapper function to override a broadcast message and send it to the WINS
238 name server instead, if it exists. if wins is false, and there has been no
239 WINS server specified, the packet will NOT be sent.
240 ****************************************************************************/
241 struct response_record *queue_netbios_pkt_wins(
242 int fd,int quest_type,enum state_type state,
243 char *name,int name_type,int nb_flags, time_t ttl,
244 int server_type, char *my_name, char *my_comment,
245 struct in_addr send_ip, struct in_addr reply_to_ip)
247 /* XXXX note: please see rfc1001.txt section 10 for details on this
248 function: it is currently inappropriate to use this - it will do
249 for now - once there is a clarification of B, M and P nodes and
250 which one samba is supposed to be
253 if ((!lp_wins_support()) && (*lp_wins_server()))
255 /* samba is not a WINS server, and we are using a WINS server */
256 struct in_addr real_wins_ip;
257 real_wins_ip = *interpret_addr2(lp_wins_server());
259 if (!zero_ip(real_wins_ip))
261 send_ip = real_wins_ip;
263 else
265 /* oops. smb.conf's wins server parameter MUST be a host_name
266 or an ip_address. */
267 DEBUG(0,("invalid smb.conf parameter 'wins server'\n"));
271 if (zero_ip(send_ip)) return NULL;
273 return queue_netbios_packet(wins_client_subnet,fd, quest_type, state,
274 name, name_type, nb_flags, ttl,
275 server_type,my_name,my_comment,
276 False, True, send_ip, reply_to_ip, 0);
280 /****************************************************************************
281 initiate a netbios name query to find someone's or someones' IP
282 this is intended to be used (not exclusively) for broadcasting to
283 master browsers (WORKGROUP(1d or 1b) or __MSBROWSE__(1)) to get
284 complete lists across a wide area network
285 ****************************************************************************/
286 struct response_record *queue_netbios_packet(struct subnet_record *d,
287 int fd,int quest_type,enum state_type state,char *name,
288 int name_type,int nb_flags, time_t ttl,
289 int server_type, char *my_name, char *my_comment,
290 BOOL bcast,BOOL recurse,
291 struct in_addr send_ip, struct in_addr reply_to_ip,
292 int reply_id)
294 struct response_record *n;
295 uint16 id = 0xffff;
297 /* ha ha. no. do NOT broadcast to 255.255.255.255: it's a pseudo address */
298 if (ip_equal(wins_ip, send_ip)) return NULL;
300 initiate_netbios_packet(&id, fd, quest_type, name, name_type,
301 nb_flags, bcast, recurse, send_ip);
303 if (id == 0xffff) {
304 DEBUG(4,("did not initiate netbios packet: %s\n", inet_ntoa(send_ip)));
305 return NULL;
308 if ((n = make_response_queue_record(state,id,fd,
309 quest_type,name,name_type,nb_flags,ttl,
310 server_type,my_name, my_comment,
311 bcast,recurse,send_ip,reply_to_ip,
312 reply_id)))
314 add_response_record(d,n);
315 return n;
317 return NULL;