Lots of changes!
[samba.git] / source / libsmb / nmblib.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    NBT netbios library routines
5    Copyright (C) Andrew Tridgell 1994-1995
6    
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.
11    
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.
16    
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.
20    
21 */
22
23 #include "includes.h"
24 #include "nameserv.h"
25
26 extern int DEBUGLEVEL;
27
28 int num_good_sends=0;
29 int  num_good_receives=0;
30 static uint16 name_trn_id = 0;
31 BOOL CanRecurse = True;
32 extern pstring scope;
33
34 /*******************************************************************
35   handle "compressed" name pointers
36   ******************************************************************/
37 static BOOL handle_name_ptrs(unsigned char *ubuf,int *offset,int length,
38                              BOOL *got_pointer,int *ret)
39 {
40   int loop_count=0;
41
42   while ((ubuf[*offset] & 0xC0) == 0xC0) {
43     if (!*got_pointer) (*ret) += 2;
44     (*got_pointer)=True;
45     (*offset) = ((ubuf[*offset] & ~0xC0)<<8) | ubuf[(*offset)+1];
46     if (loop_count++ == 10 || (*offset) < 0 || (*offset)>(length-2)) {
47       return(False);
48     }
49   }
50   return(True);
51 }
52
53 /*******************************************************************
54   parse a nmb name from "compressed" format to something readable
55   return the space taken by the name, or 0 if the name is invalid
56   ******************************************************************/
57 static int parse_nmb_name(char *inbuf,int offset,int length,
58                           struct nmb_name *name)
59 {
60   int m,n=0;
61   unsigned char *ubuf = (unsigned char *)inbuf;
62   int ret = 0;
63   BOOL got_pointer=False;
64
65   if (length - offset < 2) return(0);  
66
67   /* handle initial name pointers */
68   if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) return(0);
69   
70   m = ubuf[offset];
71
72   if (!m) return(0);
73   if ((m & 0xC0) || offset+m+2 > length) return(0);
74
75   bzero((char *)name,sizeof(*name));
76
77   /* the "compressed" part */
78   if (!got_pointer) ret += m + 2;
79   offset++;
80   while (m) {
81     unsigned char c1,c2;
82     c1 = ubuf[offset++]-'A';
83     c2 = ubuf[offset++]-'A';
84     if ((c1 & 0xF0) || (c2 & 0xF0)) return(0);
85     name->name[n++] = (c1<<4) | c2;
86     m -= 2;
87   }
88   name->name[n] = 0;
89
90   if (n==16) {
91     /* parse out the name type, 
92        its always in the 16th byte of the name */
93     name->name_type = name->name[15];
94   
95     /* remove trailing spaces */
96     name->name[15] = 0;
97     n = 14;
98     while (n && name->name[n]==' ') name->name[n--] = 0;  
99   }
100
101   /* now the domain parts (if any) */
102   n = 0;
103   while ((m=ubuf[offset])) {
104     /* we can have pointers within the domain part as well */
105     if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) return(0);
106
107     if (!got_pointer) ret += m+1;
108     if (n) name->scope[n++] = '.';
109     if (m+2+offset>length || n+m+1>sizeof(name->scope)) return(0);
110     offset++;
111     while (m--) name->scope[n++] = (char)ubuf[offset++];
112   }
113   name->scope[n++] = 0;  
114
115   return(ret);
116 }
117
118
119 /*******************************************************************
120   put a compressed nmb name into a buffer. return the length of the
121   compressed name
122
123   compressed names are really weird. The "compression" doubles the
124   size. The idea is that it also means that compressed names conform
125   to the doman name system. See RFC1002.
126   ******************************************************************/
127 static int put_nmb_name(char *buf,int offset,struct nmb_name *name)
128 {
129   int ret,m;
130   fstring buf1;
131   char *p;
132
133   if (name->name[0] == '*') {
134     /* special case for wildcard name */
135     bzero(buf1,20);
136     buf1[0] = '*';
137   } else {
138     sprintf(buf1,"%-15.15s%c",name->name,name->name_type);
139   }
140
141   buf[offset] = 0x20;
142
143   ret = 34;
144
145   for (m=0;m<16;m++) {
146     buf[offset+1+2*m] = 'A' + ((buf1[m]>>4)&0xF);
147     buf[offset+2+2*m] = 'A' + (buf1[m]&0xF);
148   }
149   offset += 33;
150
151   buf[offset] = 0;
152
153   if (name->scope[0]) {
154     /* XXXX this scope handling needs testing */
155     ret += strlen(name->scope) + 1;
156     strcpy(&buf[offset+1],name->scope);  
157   
158     p = &buf[offset+1];
159     while ((p = strchr(p,'.'))) {
160       buf[offset] = PTR_DIFF(p,&buf[offset]);
161       offset += buf[offset];
162       p = &buf[offset+1];
163     }
164     buf[offset] = strlen(&buf[offset+1]);
165   }
166
167   return(ret);
168 }
169
170 /*******************************************************************
171   useful for debugging messages
172   ******************************************************************/
173 char *namestr(struct nmb_name *n)
174 {
175   static int i=0;
176   static fstring ret[4];
177   char *p = ret[i];
178
179   if (!n->scope[0])
180     sprintf(p,"%s(%x)",n->name,n->name_type);
181   else
182     sprintf(p,"%s(%x).%s",n->name,n->name_type,n->scope);
183
184   i = (i+1)%4;
185   return(p);
186 }
187
188 /*******************************************************************
189   allocate are parse some resource records
190   ******************************************************************/
191 static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length,
192                                 struct res_rec **recs,
193                                 int count)
194 {
195   int i;
196   *recs = (struct res_rec *)malloc(sizeof(**recs)*count);
197   if (!*recs) return(False);
198
199   bzero(*recs,sizeof(**recs)*count);
200
201   for (i=0;i<count;i++) {
202     int l = parse_nmb_name(inbuf,*offset,length,&(*recs)[i].rr_name);
203     (*offset) += l;
204     if (!l || (*offset)+10 > length) {
205       free(*recs);
206       return(False);
207     }
208     (*recs)[i].rr_type = RSVAL(inbuf,(*offset));
209     (*recs)[i].rr_class = RSVAL(inbuf,(*offset)+2);
210     (*recs)[i].ttl = RIVAL(inbuf,(*offset)+4);
211     (*recs)[i].rdlength = RSVAL(inbuf,(*offset)+8);
212     (*offset) += 10;
213     if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) || 
214         (*offset)+(*recs)[i].rdlength > length) {
215       free(*recs);
216       return(False);
217     }
218     memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength);
219     (*offset) += (*recs)[i].rdlength;    
220   }
221   return(True);
222 }
223
224 /*******************************************************************
225   put a resource record into a packet
226   ******************************************************************/
227 static int put_res_rec(char *buf,int offset,struct res_rec *recs,int count)
228 {
229   int ret=0;
230   int i;
231
232   for (i=0;i<count;i++) {
233     int l = put_nmb_name(buf,offset,&recs[i].rr_name);
234     offset += l;
235     ret += l;
236     RSSVAL(buf,offset,recs[i].rr_type);
237     RSSVAL(buf,offset+2,recs[i].rr_class);
238     RSIVAL(buf,offset+4,recs[i].ttl);
239     RSSVAL(buf,offset+8,recs[i].rdlength);
240     memcpy(buf+offset+10,recs[i].rdata,recs[i].rdlength);
241     offset += 10+recs[i].rdlength;
242     ret += 10+recs[i].rdlength;
243   }
244
245   return(ret);
246 }
247
248 /*******************************************************************
249   parse a dgram packet. Return False if the packet can't be parsed 
250   or is invalid for some reason, True otherwise 
251
252   this is documented in section 4.4.1 of RFC1002
253   ******************************************************************/
254 static BOOL parse_dgram(char *inbuf,int length,struct dgram_packet *dgram)
255 {
256   int offset;
257   int flags;
258
259   bzero((char *)dgram,sizeof(*dgram));
260
261   if (length < 14) return(False);
262
263   dgram->header.msg_type = CVAL(inbuf,0);
264   flags = CVAL(inbuf,1);
265   dgram->header.flags.node_type = (enum node_type)((flags>>2)&3);
266   if (flags & 1) dgram->header.flags.more = True;
267   if (flags & 2) dgram->header.flags.first = True;
268   dgram->header.dgm_id = RSVAL(inbuf,2);
269   putip((char *)&dgram->header.source_ip,inbuf+4);
270   dgram->header.source_port = RSVAL(inbuf,8);
271   dgram->header.dgm_length = RSVAL(inbuf,10);
272   dgram->header.packet_offset = RSVAL(inbuf,12);
273
274   offset = 14;
275
276   if (dgram->header.msg_type == 0x10 ||
277       dgram->header.msg_type == 0x11 ||
278       dgram->header.msg_type == 0x12) {      
279     offset += parse_nmb_name(inbuf,offset,length,&dgram->source_name);
280     offset += parse_nmb_name(inbuf,offset,length,&dgram->dest_name);
281   }
282
283   if (offset >= length || (length-offset > sizeof(dgram->data))) 
284     return(False);
285
286   dgram->datasize = length-offset;
287   memcpy(dgram->data,inbuf+offset,dgram->datasize);
288
289   return(True);
290 }
291
292
293 /*******************************************************************
294   parse a nmb packet. Return False if the packet can't be parsed 
295   or is invalid for some reason, True otherwise 
296   ******************************************************************/
297 static BOOL parse_nmb(char *inbuf,int length,struct nmb_packet *nmb)
298 {
299   int nm_flags,offset;
300
301   bzero((char *)nmb,sizeof(*nmb));
302
303   if (length < 12) return(False);
304
305   /* parse the header */
306   nmb->header.name_trn_id = RSVAL(inbuf,0);
307   nmb->header.opcode = (CVAL(inbuf,2) >> 3) & 0xF;
308   nmb->header.response = ((CVAL(inbuf,2)>>7)&1)?True:False;
309   nm_flags = ((CVAL(inbuf,2) & 0x7) << 4) + (CVAL(inbuf,3)>>4);
310   nmb->header.nm_flags.bcast = (nm_flags&1)?True:False;
311   nmb->header.nm_flags.recursion_available = (nm_flags&8)?True:False;
312   nmb->header.nm_flags.recursion_desired = (nm_flags&0x10)?True:False;
313   nmb->header.nm_flags.trunc = (nm_flags&0x20)?True:False;
314   nmb->header.nm_flags.authoritative = (nm_flags&0x40)?True:False;
315   nmb->header.rcode = CVAL(inbuf,3) & 0xF;
316   nmb->header.qdcount = RSVAL(inbuf,4);
317   nmb->header.ancount = RSVAL(inbuf,6);
318   nmb->header.nscount = RSVAL(inbuf,8);
319   nmb->header.arcount = RSVAL(inbuf,10);
320   
321   if (nmb->header.qdcount) {
322     offset = parse_nmb_name(inbuf,12,length,&nmb->question.question_name);
323     if (!offset) return(False);
324
325     if (length - (12+offset) < 4) return(False);
326     nmb->question.question_type = RSVAL(inbuf,12+offset);
327     nmb->question.question_class = RSVAL(inbuf,12+offset+2);
328
329     offset += 12+4;
330   } else {
331     offset = 12;
332   }
333
334   /* and any resource records */
335   if (nmb->header.ancount && 
336       !parse_alloc_res_rec(inbuf,&offset,length,&nmb->answers,
337                            nmb->header.ancount))
338     return(False);
339
340   if (nmb->header.nscount && 
341       !parse_alloc_res_rec(inbuf,&offset,length,&nmb->nsrecs,
342                            nmb->header.nscount))
343     return(False);
344   
345   if (nmb->header.arcount && 
346       !parse_alloc_res_rec(inbuf,&offset,length,&nmb->additional,
347                            nmb->header.arcount))
348     return(False);
349
350   return(True);
351 }
352
353 /*******************************************************************
354   free up any resources associated with an nmb packet
355   ******************************************************************/
356 void free_nmb_packet(struct nmb_packet *nmb)
357 {  
358   if (nmb->answers) free(nmb->answers);
359   if (nmb->nsrecs) free(nmb->nsrecs);
360   if (nmb->additional) free(nmb->additional);
361 }
362
363 /*******************************************************************
364   free up any resources associated with a packet
365   ******************************************************************/
366 void free_packet(struct packet_struct *packet)
367 {  
368   if (packet->packet_type == NMB_PACKET)
369     free_nmb_packet(&packet->packet.nmb);
370   free(packet);
371 }
372
373 /*******************************************************************
374   read a packet from a socket and parse it, returning a packet ready
375   to be used or put on the queue. This assumes a UDP socket
376   ******************************************************************/
377 struct packet_struct *read_packet(int fd,enum packet_type packet_type)
378 {
379   extern struct in_addr lastip;
380   extern int lastport;
381   struct packet_struct *packet;
382   char buf[MAX_DGRAM_SIZE];
383   int length;
384   BOOL ok=False;
385
386   length = read_udp_socket(fd,buf,sizeof(buf));
387   if (length < MIN_DGRAM_SIZE) return(NULL);
388
389   packet = (struct packet_struct *)malloc(sizeof(*packet));
390   if (!packet) return(NULL);
391
392   packet->next = NULL;
393   packet->prev = NULL;
394   packet->ip = lastip;
395   packet->port = lastport;
396   packet->fd = fd;
397   packet->timestamp = time(NULL);
398   packet->packet_type = packet_type;
399   switch (packet_type) 
400     {
401     case NMB_PACKET:
402       ok = parse_nmb(buf,length,&packet->packet.nmb);
403       break;
404
405     case DGRAM_PACKET:
406       ok = parse_dgram(buf,length,&packet->packet.dgram);
407       break;
408     }
409   if (!ok) {
410     free(packet);
411     return(NULL);
412   }
413
414   num_good_receives++;
415
416   DEBUG(4,("%s received a packet of len %d from (%s) port %d\n",
417            timestring(),length,inet_ntoa(packet->ip),packet->port));
418
419   return(packet);
420 }
421                                          
422
423 /*******************************************************************
424   send a udp packet on a already open socket
425   ******************************************************************/
426 static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port)
427 {
428   BOOL ret;
429   struct sockaddr_in sock_out;
430
431   /* set the address and port */
432   bzero((char *)&sock_out,sizeof(sock_out));
433   putip((char *)&sock_out.sin_addr,(char *)&ip);
434   sock_out.sin_port = htons( port );
435   sock_out.sin_family = AF_INET;
436   
437   DEBUG(4,("%s sending a packet of len %d to (%s) on port %d\n",
438            timestring(),len,inet_ntoa(ip),port));
439         
440   ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out,
441                 sizeof(sock_out)) >= 0);
442
443   if (!ret)
444     DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n",
445              inet_ntoa(ip),port,strerror(errno)));
446
447   if (ret)
448     num_good_sends++;
449
450   return(ret);
451 }
452
453 /*******************************************************************
454   build a dgram packet ready for sending
455
456   XXXX This currently doesn't handle packets too big for one
457   datagram. It should split them and use the packet_offset, more and
458   first flags to handle the fragmentation. Yuck.
459   ******************************************************************/
460 static int build_dgram(char *buf,struct packet_struct *p)
461 {
462   struct dgram_packet *dgram = &p->packet.dgram;
463   unsigned char *ubuf = (unsigned char *)buf;
464   int offset=0;
465
466   /* put in the header */
467   ubuf[0] = dgram->header.msg_type;
468   ubuf[1] = (((int)dgram->header.flags.node_type)<<2);
469   if (dgram->header.flags.more) ubuf[1] |= 1;
470   if (dgram->header.flags.first) ubuf[1] |= 2;
471   RSSVAL(ubuf,2,dgram->header.dgm_id);
472   putip(ubuf+4,(char *)&dgram->header.source_ip);
473   RSSVAL(ubuf,8,dgram->header.source_port);
474   RSSVAL(ubuf,12,dgram->header.packet_offset);
475
476   offset = 14;
477
478   if (dgram->header.msg_type == 0x10 ||
479       dgram->header.msg_type == 0x11 ||
480       dgram->header.msg_type == 0x12) {      
481     offset += put_nmb_name((char *)ubuf,offset,&dgram->source_name);
482     offset += put_nmb_name((char *)ubuf,offset,&dgram->dest_name);
483   }
484
485   memcpy(ubuf+offset,dgram->data,dgram->datasize);
486   offset += dgram->datasize;
487
488   /* automatically set the dgm_length */
489   dgram->header.dgm_length = offset;
490   RSSVAL(ubuf,10,dgram->header.dgm_length); 
491
492   return(offset);
493 }
494
495 /*******************************************************************
496   build a nmb name
497   ******************************************************************/
498 void make_nmb_name(struct nmb_name *n,char *name,int type,char *this_scope)
499 {
500   strcpy(n->name,name);
501   strupper(n->name);
502   n->name_type = type;
503   strcpy(n->scope,this_scope);
504 }
505
506
507 /*******************************************************************
508   build a nmb packet ready for sending
509
510   XXXX this currently relies on not being passed something that expands
511   to a packet too big for the buffer. Eventually this should be
512   changed to set the trunc bit so the receiver can request the rest
513   via tcp (when that becomes supported)
514   ******************************************************************/
515 static int build_nmb(char *buf,struct packet_struct *p)
516 {
517   struct nmb_packet *nmb = &p->packet.nmb;
518   unsigned char *ubuf = (unsigned char *)buf;
519   int offset=0;
520
521   /* put in the header */
522   RSSVAL(ubuf,offset,nmb->header.name_trn_id);
523   ubuf[offset+2] = (nmb->header.opcode & 0xF) << 3;
524   if (nmb->header.response) ubuf[offset+2] |= (1<<7);
525   if (nmb->header.nm_flags.authoritative) ubuf[offset+2] |= 0x4;
526   if (nmb->header.nm_flags.trunc) ubuf[offset+2] |= 0x2;
527   if (nmb->header.nm_flags.recursion_desired) ubuf[offset+2] |= 0x1;
528   if (nmb->header.nm_flags.recursion_available) ubuf[offset+3] |= 0x80;
529   if (nmb->header.nm_flags.bcast) ubuf[offset+3] |= 0x10;
530   ubuf[offset+3] |= (nmb->header.rcode & 0xF);
531   RSSVAL(ubuf,offset+4,nmb->header.qdcount);
532   RSSVAL(ubuf,offset+6,nmb->header.ancount);
533   RSSVAL(ubuf,offset+8,nmb->header.nscount);
534   RSSVAL(ubuf,offset+10,nmb->header.arcount);
535   
536   offset += 12;
537   if (nmb->header.qdcount) {
538     /* XXXX this doesn't handle a qdcount of > 1 */
539     offset += put_nmb_name((char *)ubuf,offset,&nmb->question.question_name);
540     RSSVAL(ubuf,offset,nmb->question.question_type);
541     RSSVAL(ubuf,offset+2,nmb->question.question_class);
542     offset += 4;
543   }
544
545   if (nmb->header.ancount)
546     offset += put_res_rec((char *)ubuf,offset,nmb->answers,
547                           nmb->header.ancount);
548
549   if (nmb->header.nscount)
550     offset += put_res_rec((char *)ubuf,offset,nmb->nsrecs,
551                           nmb->header.nscount);
552
553   if (nmb->header.arcount)
554     offset += put_res_rec((char *)ubuf,offset,nmb->additional,
555                           nmb->header.arcount);  
556
557   return(offset);
558 }
559
560
561 /*******************************************************************
562   send a packet_struct
563   ******************************************************************/
564 BOOL send_packet(struct packet_struct *p)
565 {
566   char buf[1024];
567   int len=0;
568
569   bzero(buf,sizeof(buf));
570
571   switch (p->packet_type) 
572     {
573     case NMB_PACKET:
574       len = build_nmb(buf,p);
575       break;
576
577     case DGRAM_PACKET:
578       len = build_dgram(buf,p);
579       break;
580     }
581
582   if (!len) return(False);
583
584   return(send_udp(p->fd,buf,len,p->ip,p->port));
585 }
586
587 /****************************************************************************
588   receive a packet with timeout on a open UDP filedescriptor
589   The timeout is in milliseconds
590   ***************************************************************************/
591 struct packet_struct *receive_packet(int fd,enum packet_type type,int t)
592 {
593   fd_set fds;
594   struct timeval timeout;
595
596   FD_ZERO(&fds);
597   FD_SET(fd,&fds);
598   timeout.tv_sec = t/1000;
599   timeout.tv_usec = 1000*(t%1000);
600
601   sys_select(&fds,&timeout);
602
603   if (FD_ISSET(fd,&fds)) 
604     return(read_packet(fd,type));
605
606   return(NULL);
607 }
608
609
610 /****************************************************************************
611 interpret a node status response
612 ****************************************************************************/
613 static void interpret_node_status(char *p, char *master,char *rname)
614 {
615   int level = (master||rname)?4:0;
616   int numnames = CVAL(p,0);
617   DEBUG(level,("received %d names\n",numnames));
618
619   if (rname) *rname = 0;
620   if (master) *master = 0;
621
622   p += 1;
623   while (numnames--)
624     {
625       char qname[17];
626       int type;
627       fstring flags;
628       int i;
629       *flags = 0;
630       StrnCpy(qname,p,15);
631       type = CVAL(p,15);
632       p += 16;
633
634       strcat(flags, (p[0] & 0x80) ? "<GROUP> " : "        ");
635       if ((p[0] & 0x60) == 0x00) strcat(flags,"B ");
636       if ((p[0] & 0x60) == 0x20) strcat(flags,"P ");
637       if ((p[0] & 0x60) == 0x40) strcat(flags,"M ");
638       if ((p[0] & 0x60) == 0x60) strcat(flags,"_ ");
639       if (p[0] & 0x10) strcat(flags,"<DEREGISTERING> ");
640       if (p[0] & 0x08) strcat(flags,"<CONFLICT> ");
641       if (p[0] & 0x04) strcat(flags,"<ACTIVE> ");
642       if (p[0] & 0x02) strcat(flags,"<PERMANENT> ");
643
644       if (master && !*master && type == 0x1d) {
645         StrnCpy(master,qname,15);
646         trim_string(master,NULL," ");
647       }
648
649       if (rname && !*rname && type == 0x20 && !(p[0]&0x80)) {
650         StrnCpy(rname,qname,15);
651         trim_string(rname,NULL," ");
652       }
653       
654       for (i = strlen( qname) ; --i >= 0 ; ) {
655         if (!isprint(qname[i])) qname[i] = '.';
656       }
657       DEBUG(level,("\t%-15s <%02x> - %s\n",qname,type,flags));
658       p+=2;
659     }
660   DEBUG(level,("num_good_sends=%d num_good_receives=%d\n",
661                IVAL(p,20),IVAL(p,24)));
662 }
663
664
665 /****************************************************************************
666   do a netbios name status query on a host
667
668   the "master" parameter is a hack used for finding workgroups.
669   **************************************************************************/
670 BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
671                  struct in_addr to_ip,char *master,char *rname,
672                  void (*fn)())
673 {
674   BOOL found=False;
675   int retries = 2;
676   int retry_time = 5000;
677   struct timeval tval;
678   struct packet_struct p;
679   struct packet_struct *p2;
680   struct nmb_packet *nmb = &p.packet.nmb;
681
682   bzero((char *)&p,sizeof(p));
683
684   if (!name_trn_id) name_trn_id = (time(NULL)%(unsigned)0x7FFF) + 
685     (getpid()%(unsigned)100);
686   name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
687
688   nmb->header.name_trn_id = name_trn_id;
689   nmb->header.opcode = 0;
690   nmb->header.response = False;
691   nmb->header.nm_flags.bcast = False;
692   nmb->header.nm_flags.recursion_available = CanRecurse;
693   nmb->header.nm_flags.recursion_desired = recurse;
694   nmb->header.nm_flags.trunc = False;
695   nmb->header.nm_flags.authoritative = False;
696   nmb->header.rcode = 0;
697   nmb->header.qdcount = 1;
698   nmb->header.ancount = 0;
699   nmb->header.nscount = 0;
700   nmb->header.arcount = 0;
701
702   make_nmb_name(&nmb->question.question_name,name,name_type,scope);
703
704   nmb->question.question_type = 0x21;
705   nmb->question.question_class = 0x1;
706
707   p.ip = to_ip;
708   p.port = NMB_PORT;
709   p.fd = fd;
710   p.timestamp = time(NULL);
711   p.packet_type = NMB_PACKET;
712
713   GetTimeOfDay(&tval);
714
715   if (!send_packet(&p)) 
716     return(False);
717
718   retries--;
719
720   while (1)
721     {
722       struct timeval tval2;
723       GetTimeOfDay(&tval2);
724       if (TvalDiff(&tval,&tval2) > retry_time) {
725         if (!retries) break;
726         if (!found && !send_packet(&p))
727           return False;
728         GetTimeOfDay(&tval);
729         retries--;
730       }
731
732       if ((p2=receive_packet(fd,NMB_PACKET,90)))
733         {     
734           struct nmb_packet *nmb2 = &p2->packet.nmb;
735           if (nmb->header.name_trn_id != nmb2->header.name_trn_id ||
736               !nmb2->header.response) {
737             /* its not for us - maybe deal with it later */
738             if (fn) 
739               fn(p2);
740             else
741               free_packet(p2);
742             continue;
743           }
744           
745           if (nmb2->header.opcode != 0 ||
746               nmb2->header.nm_flags.bcast ||
747               nmb2->header.rcode ||
748               !nmb2->header.ancount ||
749               nmb2->answers->rr_type != 0x21) {
750             /* XXXX what do we do with this? could be a redirect, but
751                we'll discard it for the moment */
752             free_packet(p2);
753             continue;
754           }
755
756           interpret_node_status(&nmb2->answers->rdata[0], master,rname);
757           free_packet(p2);
758           return(True);
759         }
760     }
761   
762
763   DEBUG(0,("No status response (this is not unusual)\n"));
764
765   return(False);
766 }
767
768
769 /****************************************************************************
770   do a netbios name query to find someones IP
771   ****************************************************************************/
772 BOOL name_query(int fd,char *name,int name_type, 
773                 BOOL bcast,BOOL recurse,
774                 struct in_addr to_ip, struct in_addr *ip,void (*fn)())
775 {
776   BOOL found=False;
777   int retries = 3;
778   int retry_time = bcast?250:2000;
779   struct timeval tval;
780   struct packet_struct p;
781   struct packet_struct *p2;
782   struct nmb_packet *nmb = &p.packet.nmb;
783
784   bzero((char *)&p,sizeof(p));
785
786   if (!name_trn_id) name_trn_id = (time(NULL)%(unsigned)0x7FFF) + 
787     (getpid()%(unsigned)100);
788   name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
789
790   nmb->header.name_trn_id = name_trn_id;
791   nmb->header.opcode = 0;
792   nmb->header.response = False;
793   nmb->header.nm_flags.bcast = bcast;
794   nmb->header.nm_flags.recursion_available = CanRecurse;
795   nmb->header.nm_flags.recursion_desired = recurse;
796   nmb->header.nm_flags.trunc = False;
797   nmb->header.nm_flags.authoritative = False;
798   nmb->header.rcode = 0;
799   nmb->header.qdcount = 1;
800   nmb->header.ancount = 0;
801   nmb->header.nscount = 0;
802   nmb->header.arcount = 0;
803
804   make_nmb_name(&nmb->question.question_name,name,name_type,scope);
805
806   nmb->question.question_type = 0x20;
807   nmb->question.question_class = 0x1;
808
809   p.ip = to_ip;
810   p.port = NMB_PORT;
811   p.fd = fd;
812   p.timestamp = time(NULL);
813   p.packet_type = NMB_PACKET;
814
815   GetTimeOfDay(&tval);
816
817   if (!send_packet(&p)) 
818     return(False);
819
820   retries--;
821
822   while (1)
823     {
824       struct timeval tval2;
825       GetTimeOfDay(&tval2);
826       if (TvalDiff(&tval,&tval2) > retry_time) {
827         if (!retries) break;
828         if (!found && !send_packet(&p))
829           return False;
830         GetTimeOfDay(&tval);
831         retries--;
832       }
833
834       if ((p2=receive_packet(fd,NMB_PACKET,90)))
835         {     
836           struct nmb_packet *nmb2 = &p2->packet.nmb;
837           if (nmb->header.name_trn_id != nmb2->header.name_trn_id ||
838               !nmb2->header.response) {
839             /* its not for us - maybe deal with it later 
840                (put it on the queue?) */
841             if (fn) 
842               fn(p2);
843             else
844               free_packet(p2);
845             continue;
846           }
847           
848           if (nmb2->header.opcode != 0 ||
849               nmb2->header.nm_flags.bcast ||
850               nmb2->header.rcode ||
851               !nmb2->header.ancount) {
852             /* XXXX what do we do with this? could be a redirect, but
853                we'll discard it for the moment */
854             free_packet(p2);
855             continue;
856           }
857
858           if (ip) {
859             putip((char *)ip,&nmb2->answers->rdata[2]);
860             DEBUG(fn?3:2,("Got a positive name query response from %s",
861                           inet_ntoa(p2->ip)));
862             DEBUG(fn?3:2,(" (%s)\n",inet_ntoa(*ip)));
863           }
864           found=True; retries=0;
865           free_packet(p2);
866           if (fn) break;
867         }
868     }
869
870   return(found);
871 }
872
873
874 /****************************************************************************
875   construct and send a netbios DGRAM
876
877   Note that this currently sends all answers to port 138. thats the
878   wrong things to do! I should send to the requestors port. XXX
879   **************************************************************************/
880 BOOL send_mailslot_reply(char *mailslot,int fd,char *buf,int len,
881                          char *srcname,char *dstname,
882                          int src_type,int dest_type,
883                          struct in_addr dest_ip,
884                          struct in_addr src_ip)
885 {
886   struct packet_struct p;
887   struct dgram_packet *dgram = &p.packet.dgram;
888   char *ptr,*p2;
889   char tmp[4];
890
891   bzero((char *)&p,sizeof(p));
892
893   dgram->header.msg_type = 0x11; /* DIRECT GROUP DATAGRAM */
894   dgram->header.flags.node_type = M_NODE;
895   dgram->header.flags.first = True;
896   dgram->header.flags.more = False;
897   dgram->header.dgm_id = name_trn_id++;
898   dgram->header.source_ip = src_ip;
899   dgram->header.source_port = DGRAM_PORT;
900   dgram->header.dgm_length = 0; /* let build_dgram() handle this */
901   dgram->header.packet_offset = 0;
902   
903   make_nmb_name(&dgram->source_name,srcname,src_type,scope);
904   make_nmb_name(&dgram->dest_name,dstname,dest_type,scope);
905
906   ptr = &dgram->data[0];
907
908   /* now setup the smb part */
909   ptr -= 4; /* XXX ugliness because of handling of tcp SMB length */
910   memcpy(tmp,ptr,4);
911   set_message(ptr,17,17 + len,True);
912   memcpy(ptr,tmp,4);
913
914   CVAL(ptr,smb_com) = SMBtrans;
915   SSVAL(ptr,smb_vwv1,len);
916   SSVAL(ptr,smb_vwv11,len);
917   SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
918   SSVAL(ptr,smb_vwv13,3);
919   SSVAL(ptr,smb_vwv14,1);
920   SSVAL(ptr,smb_vwv15,1);
921   SSVAL(ptr,smb_vwv16,2);
922   p2 = smb_buf(ptr);
923   strcpy(p2,mailslot);
924   p2 = skip_string(p2,1);
925
926   memcpy(p2,buf,len);
927   p2 += len;
928
929   dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length */
930
931   p.ip = dest_ip;
932   p.port = DGRAM_PORT;
933   p.fd = fd;
934   p.timestamp = time(NULL);
935   p.packet_type = DGRAM_PACKET;
936
937   return(send_packet(&p));
938 }
939
940