2 Unix SMB/Netbios implementation.
4 NBT netbios library routines
5 Copyright (C) Andrew Tridgell 1994-1995
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.
26 extern int ClientDGRAM;
28 extern struct subnet_record *subnetlist;
30 extern int DEBUGLEVEL;
32 static uint16 name_trn_id=0;
33 BOOL CanRecurse = True;
35 extern pstring myname;
36 extern struct in_addr ipzero;
37 extern struct in_addr ipgrp;
39 int num_response_packets = 0;
41 /***************************************************************************
42 updates the unique transaction identifier
43 **************************************************************************/
44 static void update_name_trn_id(void)
48 name_trn_id = (time(NULL)%(unsigned)0x7FFF) + (getpid()%(unsigned)100);
50 name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
54 /***************************************************************************
55 add an initated name query into the list
56 **************************************************************************/
57 static void add_response_record(struct subnet_record *d,
58 struct response_record *n)
60 struct response_record *n2;
72 for (n2 = d->responselist; n2->next; n2 = n2->next) ;
80 /***************************************************************************
81 deals with an entry before it dies
82 **************************************************************************/
83 static void dead_netbios_entry(struct subnet_record *d,
84 struct response_record *n)
86 DEBUG(3,("Removing dead netbios entry for %s %s (num_msgs=%d)\n",
87 inet_ntoa(n->to_ip), namestr(&n->name), n->num_msgs));
91 case NAME_QUERY_CONFIRM:
93 if (!lp_wins_support()) return; /* only if we're a WINS server */
97 /* oops. name query had no response. check that the name is
98 unique and then remove it from our WINS database */
100 /* IMPORTANT: see query_refresh_names() */
102 if ((!NAME_GROUP(n->nb_flags)))
104 struct subnet_record *d1 = find_subnet(ipgrp);
107 /* remove the name that had been registered with us,
108 and we're now getting no response when challenging.
109 see rfc1001.txt 15.5.2
111 remove_netbios_name(d1, n->name.name, n->name.name_type,
119 case NAME_QUERY_MST_CHK:
121 /* if no response received, the master browser must have gone
122 down on that subnet, without telling anyone. */
124 /* IMPORTANT: see response_netbios_packet() */
126 if (n->num_msgs == 0)
127 browser_gone(n->name.name, n->to_ip);
133 /* if no response received, it must be OK for us to release the
134 name. nobody objected (including a potentially dead or deaf
137 /* IMPORTANT: see response_name_release() */
139 if (ismyip(n->to_ip))
141 remove_netbios_name(d,n->name.name,n->name.name_type,SELF,n->to_ip);
145 DEBUG(1,("WINS server did not respond to name release!\n"));
152 /* if no response received, and we are using a broadcast registration
153 method, it must be OK for us to register the name: nobody objected
154 on that subnet. if we are using a WINS server, then the WINS
155 server must be dead or deaf.
159 /* broadcast method: implicit acceptance of the name registration
160 by not receiving any objections. */
162 /* IMPORTANT: see response_name_reg() */
164 enum name_source source = ismyip(n->to_ip) ? SELF : REGISTER;
166 add_netbios_entry(d,n->name.name,n->name.name_type,
167 n->nb_flags, n->ttl, source,n->to_ip, True,!n->bcast);
171 /* XXXX oops. this is where i wish this code could retry DGRAM
172 packets. we directed a name registration at a WINS server, and
173 received no response. rfc1001.txt states that after retrying,
174 we should assume the WINS server is dead, and fall back to
177 DEBUG(1,("WINS server did not respond to name registration!\n"));
184 /* nothing to do but delete the dead expected-response structure */
185 /* this is normal. */
192 /****************************************************************************
193 initiate a netbios packet
194 ****************************************************************************/
195 static void initiate_netbios_packet(uint16 *id,
196 int fd,int quest_type,char *name,int name_type,
197 int nb_flags,BOOL bcast,BOOL recurse,
198 struct in_addr to_ip)
200 struct packet_struct p;
201 struct nmb_packet *nmb = &p.packet.nmb;
202 struct res_rec additional_rec;
203 char *packet_type = "unknown";
208 if (quest_type == NMB_STATUS) { packet_type = "nmb_status"; opcode = 0; }
209 if (quest_type == NMB_QUERY ) { packet_type = "nmb_query"; opcode = 0; }
210 if (quest_type == NMB_REG ) { packet_type = "nmb_reg"; opcode = 5; }
211 if (quest_type == NMB_REL ) { packet_type = "nmb_rel"; opcode = 6; }
213 DEBUG(4,("initiating netbios packet: %s %s(%x) (bcast=%s) %s\n",
214 packet_type, name, name_type, BOOLSTR(bcast), inet_ntoa(to_ip)));
216 if (opcode == -1) return;
218 bzero((char *)&p,sizeof(p));
220 update_name_trn_id();
222 if (*id == 0xffff) *id = name_trn_id; /* allow resending with same id */
224 nmb->header.name_trn_id = *id;
225 nmb->header.opcode = opcode;
226 nmb->header.response = False;
227 nmb->header.nm_flags.bcast = bcast;
228 nmb->header.nm_flags.recursion_available = CanRecurse;
229 nmb->header.nm_flags.recursion_desired = recurse;
230 nmb->header.nm_flags.trunc = False;
231 nmb->header.nm_flags.authoritative = False;
232 nmb->header.rcode = 0;
233 nmb->header.qdcount = 1;
234 nmb->header.ancount = 0;
235 nmb->header.nscount = 0;
236 nmb->header.arcount = (quest_type==NMB_REG || quest_type==NMB_REL) ? 1 : 0;
238 make_nmb_name(&nmb->question.question_name,name,name_type,scope);
240 nmb->question.question_type = quest_type;
241 nmb->question.question_class = 0x1;
243 if (quest_type == NMB_REG || quest_type == NMB_REL)
245 nmb->additional = &additional_rec;
246 bzero((char *)nmb->additional,sizeof(*nmb->additional));
248 nmb->additional->rr_name = nmb->question.question_name;
249 nmb->additional->rr_type = nmb->question.question_type;
250 nmb->additional->rr_class = nmb->question.question_class;
252 nmb->additional->ttl = quest_type == NMB_REG ? lp_max_ttl() : 0;
253 nmb->additional->rdlength = 6;
254 nmb->additional->rdata[0] = nb_flags;
255 putip(&nmb->additional->rdata[2],(char *)iface_ip(to_ip));
261 p.timestamp = time(NULL);
262 p.packet_type = NMB_PACKET;
264 if (!send_packet(&p)) *id = 0xffff;
270 /*******************************************************************
271 remove old name response entries
272 XXXX retry code needs to be added, including a retry wait period and a count
273 see name_query() and name_status() for suggested implementation.
274 ******************************************************************/
275 void expire_netbios_response_entries()
277 struct response_record *n;
278 struct response_record *nextn;
279 struct subnet_record *d;
281 for (d = subnetlist; d; d = d->next)
282 for (n = d->responselist; n; n = nextn)
284 if (n->repeat_time < time(NULL))
286 if (n->repeat_count > 0)
288 /* resend the entry */
289 initiate_netbios_packet(&n->response_id, n->fd, n->quest_type,
290 n->name.name, n->name.name_type,
291 n->nb_flags, n->bcast, n->recurse, n->to_ip);
293 n->repeat_time += n->repeat_interval; /* XXXX ms needed */
298 dead_netbios_entry(d,n);
302 if (n->prev) n->prev->next = n->next;
303 if (n->next) n->next->prev = n->prev;
305 if (d->responselist == n) d->responselist = n->next;
309 num_response_packets--;
319 /****************************************************************************
320 reply to a netbios name packet
321 ****************************************************************************/
322 void reply_netbios_packet(struct packet_struct *p1,int trn_id,
323 int rcode,int opcode, BOOL recurse,
324 struct nmb_name *rr_name,int rr_type,int rr_class,int ttl,
327 struct packet_struct p;
328 struct nmb_packet *nmb = &p.packet.nmb;
329 struct res_rec answers;
330 char *packet_type = "unknown";
334 if (rr_type == NMB_STATUS) packet_type = "nmb_status";
335 if (rr_type == NMB_QUERY ) packet_type = "nmb_query";
336 if (rr_type == NMB_REG ) packet_type = "nmb_reg";
337 if (rr_type == NMB_REL ) packet_type = "nmb_rel";
339 DEBUG(4,("replying netbios packet: %s %s\n",
340 packet_type, namestr(rr_name), inet_ntoa(p.ip)));
342 nmb->header.name_trn_id = trn_id;
343 nmb->header.opcode = opcode;
344 nmb->header.response = True;
345 nmb->header.nm_flags.bcast = False;
346 nmb->header.nm_flags.recursion_available = recurse;
347 nmb->header.nm_flags.recursion_desired = True;
348 nmb->header.nm_flags.trunc = False;
349 nmb->header.nm_flags.authoritative = True;
351 nmb->header.qdcount = 0;
352 nmb->header.ancount = 1;
353 nmb->header.nscount = 0;
354 nmb->header.arcount = 0;
355 nmb->header.rcode = 0;
357 bzero((char*)&nmb->question,sizeof(nmb->question));
359 nmb->answers = &answers;
360 bzero((char*)nmb->answers,sizeof(*nmb->answers));
362 nmb->answers->rr_name = *rr_name;
363 nmb->answers->rr_type = rr_type;
364 nmb->answers->rr_class = rr_class;
365 nmb->answers->ttl = ttl;
369 nmb->answers->rdlength = len;
370 memcpy(nmb->answers->rdata, data, len);
373 p.packet_type = NMB_PACKET;
375 debug_nmb_packet(&p);
381 /****************************************************************************
382 wrapper function to override a broadcast message and send it to the WINS
383 name server instead, if it exists. if wins is false, and there has been no
384 WINS server specified, the packet will NOT be sent.
385 ****************************************************************************/
386 void queue_netbios_pkt_wins(struct subnet_record *d,
387 int fd,int quest_type,enum state_type state,
388 char *name,int name_type,int nb_flags, time_t ttl,
389 BOOL bcast,BOOL recurse,struct in_addr to_ip)
391 /* XXXX note: please see rfc1001.txt section 10 for details on this
392 function: it is currently inappropriate to use this - it will do
393 for now - once there is a clarification of B, M and P nodes and
394 which one samba is supposed to be
397 if ((!lp_wins_support()) && (*lp_wins_server()))
399 /* samba is not a WINS server, and we are using a WINS server */
400 struct in_addr wins_ip;
401 wins_ip = *interpret_addr2(lp_wins_server());
403 if (!zero_ip(wins_ip))
410 /* oops. smb.conf's wins server parameter MUST be a host_name
412 DEBUG(0,("invalid smb.conf parameter 'wins server'\n"));
416 if (zero_ip(to_ip)) return;
418 queue_netbios_packet(d,fd, quest_type, state,
419 name, name_type, nb_flags, ttl,
420 bcast, recurse, to_ip);
423 /****************************************************************************
424 create a name query response record
425 **************************************************************************/
426 static struct response_record *
427 make_response_queue_record(enum state_type state,int id,int fd,
428 int quest_type, char *name,int type, int nb_flags, time_t ttl,
429 BOOL bcast,BOOL recurse, struct in_addr ip)
431 struct response_record *n;
433 if (!name || !name[0]) return NULL;
435 if (!(n = (struct response_record *)malloc(sizeof(*n))))
441 n->quest_type = quest_type;
442 make_nmb_name(&n->name, name, type, scope);
443 n->nb_flags = nb_flags;
446 n->recurse = recurse;
449 n->repeat_interval = 1; /* XXXX should be in ms */
451 n->repeat_time = time(NULL) + n->repeat_interval;
455 num_response_packets++; /* count of total number of packets still around */
461 /****************************************************************************
462 initiate a netbios name query to find someone's or someones' IP
463 this is intended to be used (not exclusively) for broadcasting to
464 master browsers (WORKGROUP(1d or 1b) or __MSBROWSE__(1)) to get
465 complete lists across a wide area network
466 ****************************************************************************/
467 void queue_netbios_packet(struct subnet_record *d,
468 int fd,int quest_type,enum state_type state,char *name,
469 int name_type,int nb_flags, time_t ttl,
470 BOOL bcast,BOOL recurse, struct in_addr to_ip)
472 struct in_addr wins_ip = ipgrp;
473 struct response_record *n;
476 /* ha ha. no. do NOT broadcast to 255.255.255.255: it's a pseudo address */
477 if (ip_equal(wins_ip, to_ip)) return;
479 initiate_netbios_packet(&id, fd, quest_type, name, name_type,
480 nb_flags, bcast, recurse, to_ip);
482 if (id == 0xffff) return;
484 if ((n = make_response_queue_record(state,id,fd,
485 quest_type,name,name_type,nb_flags,ttl,
486 bcast,recurse,to_ip)))
488 add_response_record(d,n);
493 /****************************************************************************
494 find a response in a subnet's name query response list.
495 **************************************************************************/
496 struct response_record *find_response_record(struct subnet_record **d,
499 struct response_record *n;
503 for ((*d) = subnetlist; (*d); (*d) = (*d)->next)
505 for (n = (*d)->responselist; n; n = n->next)
507 if (n->response_id == id) {
519 /*******************************************************************
520 the global packet linked-list. incoming entries are added to the
521 end of this list. it is supposed to remain fairly short so we
522 won't bother with an end pointer.
523 ******************************************************************/
524 static struct packet_struct *packet_queue = NULL;
526 /*******************************************************************
527 queue a packet into the packet queue
528 ******************************************************************/
529 void queue_packet(struct packet_struct *packet)
531 struct packet_struct *p;
536 packet_queue = packet;
540 /* find the bottom */
541 for (p=packet_queue;p->next;p=p->next) ;
548 /*******************************************************************
549 run elements off the packet queue till its empty
550 ******************************************************************/
551 void run_packet_queue()
553 struct packet_struct *p;
555 while ((p=packet_queue))
557 switch (p->packet_type)
568 packet_queue = packet_queue->next;
569 if (packet_queue) packet_queue->prev = NULL;
574 /****************************************************************************
575 listens for NMB or DGRAM packets, and queues them
576 ***************************************************************************/
577 void listen_for_packets(BOOL run_election)
581 struct timeval timeout;
584 FD_SET(ClientNMB,&fds);
585 FD_SET(ClientDGRAM,&fds);
587 /* during elections and when expecting a netbios response packet we need
588 to send election packets at one second intervals.
589 XXXX actually, it needs to be the interval (in ms) between time now and the
590 time we are expecting the next netbios packet */
592 timeout.tv_sec = (run_election||num_response_packets) ? 1 : NMBD_SELECT_LOOP;
595 selrtn = sys_select(&fds,&timeout);
597 if (FD_ISSET(ClientNMB,&fds))
599 struct packet_struct *packet = read_packet(ClientNMB, NMB_PACKET);
602 if (ismyip(packet->ip) &&
603 (packet->port == NMB_PORT || packet->port == DGRAM_PORT)) {
604 DEBUG(5,("discarding own packet from %s:%d\n",
605 inet_ntoa(packet->ip),packet->port));
610 queue_packet(packet);
615 if (FD_ISSET(ClientDGRAM,&fds))
617 struct packet_struct *packet = read_packet(ClientDGRAM, DGRAM_PACKET);
620 if (ismyip(packet->ip) &&
621 (packet->port == NMB_PORT || packet->port == DGRAM_PORT)) {
622 DEBUG(5,("discarding own packet from %s:%d\n",
623 inet_ntoa(packet->ip),packet->port));
628 queue_packet(packet);
636 /****************************************************************************
637 interpret a node status response. this is pretty hacked: we need two bits of
638 info. a) the name of the workgroup b) the name of the server. it will also
639 add all the names it finds into the namelist.
640 ****************************************************************************/
641 BOOL interpret_node_status(struct subnet_record *d,
642 char *p, struct nmb_name *name,int t,
643 char *serv_name, struct in_addr ip, BOOL bcast)
645 int level = t==0x20 ? 4 : 0;
646 int numnames = CVAL(p,0);
649 DEBUG(level,("received %d names\n",numnames));
653 if (serv_name) *serv_name = 0;
670 trim_string(qname,NULL," ");
674 if (NAME_GROUP (nb_flags)) { strcat(flags,"<GROUP> "); group=True;}
675 if (NAME_BFLAG (nb_flags)) { strcat(flags,"B "); }
676 if (NAME_PFLAG (nb_flags)) { strcat(flags,"P "); }
677 if (NAME_MFLAG (nb_flags)) { strcat(flags,"M "); }
678 if (NAME__FLAG (nb_flags)) { strcat(flags,"_ "); }
679 if (NAME_DEREG (nb_flags)) { strcat(flags,"<DEREGISTERING> "); }
680 if (NAME_CONFLICT (nb_flags)) { strcat(flags,"<CONFLICT> "); add=True;}
681 if (NAME_ACTIVE (nb_flags)) { strcat(flags,"<ACTIVE> "); add=True; }
682 if (NAME_PERMANENT(nb_flags)) { strcat(flags,"<PERMANENT> "); add=True;}
684 /* might as well update our namelist while we're at it */
687 struct in_addr nameip;
688 enum name_source src;
697 add_netbios_entry(d,qname,type,nb_flags,2*60*60,src,nameip,True,bcast);
700 /* we want the server name */
701 if (serv_name && !*serv_name && !group && t == 0)
703 StrnCpy(serv_name,qname,15);
707 /* looking for a name and type? */
708 if (name && !found && (t == type))
710 /* take a guess at some of the name types we're going to ask for.
711 evaluate whether they are group names or no... */
712 if (((t == 0x1b || t == 0x1d ) && !group) ||
713 ((t == 0x20 || t == 0x1c || t == 0x1e) && group))
716 make_nmb_name(name,qname,type,scope);
720 DEBUG(level,("\t%s(0x%x)\t%s\n",qname,type,flags));
722 DEBUG(level,("num_good_sends=%d num_good_receives=%d\n",
723 IVAL(p,20),IVAL(p,24)));
728 /****************************************************************************
729 construct and send a netbios DGRAM
731 Note that this currently sends all answers to port 138. thats the
732 wrong things to do! I should send to the requestors port. XXX
733 **************************************************************************/
734 BOOL send_mailslot_reply(char *mailslot,int fd,char *buf,int len,char *srcname,
735 char *dstname,int src_type,int dest_type,
736 struct in_addr dest_ip,struct in_addr src_ip)
738 struct packet_struct p;
739 struct dgram_packet *dgram = &p.packet.dgram;
740 struct in_addr wins_ip = ipgrp;
744 /* ha ha. no. do NOT send packets to 255.255.255.255: it's a pseudo address */
745 if (ip_equal(wins_ip, dest_ip)) return False;
747 bzero((char *)&p,sizeof(p));
749 update_name_trn_id();
751 dgram->header.msg_type = 0x11; /* DIRECT GROUP DATAGRAM */
752 dgram->header.flags.node_type = M_NODE;
753 dgram->header.flags.first = True;
754 dgram->header.flags.more = False;
755 dgram->header.dgm_id = name_trn_id;
756 dgram->header.source_ip = src_ip;
757 dgram->header.source_port = DGRAM_PORT;
758 dgram->header.dgm_length = 0; /* let build_dgram() handle this */
759 dgram->header.packet_offset = 0;
761 make_nmb_name(&dgram->source_name,srcname,src_type,scope);
762 make_nmb_name(&dgram->dest_name,dstname,dest_type,scope);
764 ptr = &dgram->data[0];
766 /* now setup the smb part */
767 ptr -= 4; /* XXX ugliness because of handling of tcp SMB length */
769 set_message(ptr,17,17 + len,True);
772 CVAL(ptr,smb_com) = SMBtrans;
773 SSVAL(ptr,smb_vwv1,len);
774 SSVAL(ptr,smb_vwv11,len);
775 SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
776 SSVAL(ptr,smb_vwv13,3);
777 SSVAL(ptr,smb_vwv14,1);
778 SSVAL(ptr,smb_vwv15,1);
779 SSVAL(ptr,smb_vwv16,2);
782 p2 = skip_string(p2,1);
787 dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length */
792 p.timestamp = time(NULL);
793 p.packet_type = DGRAM_PACKET;
795 return(send_packet(&p));