netbios registration and release response packets were being junked. a
[samba.git] / source / namepacket.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    NBT netbios routines and daemon - version 2
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    Revision History:
22
23    14 jan 96: lkcl@pires.co.uk
24    added multiple workgroup domain master support
25
26 */
27
28 #include "includes.h"
29
30 extern int ClientNMB;
31 extern int ClientDGRAM;
32
33 extern int DEBUGLEVEL;
34
35 extern int num_response_packets;
36
37 BOOL CanRecurse = True;
38 extern pstring scope;
39 extern struct in_addr ipgrp;
40
41 static uint16 name_trn_id=0;
42
43
44 /***************************************************************************
45   updates the unique transaction identifier
46   **************************************************************************/
47 void debug_browse_data(char *outbuf, int len)
48 {
49     int i,j;
50     for (i = 0; i < len; i+= 16)
51       {
52         DEBUG(4, ("%3x char ", i));
53         
54         for (j = 0; j < 16; j++)
55           {
56             unsigned char x = outbuf[i+j];
57             if (x < 32 || x > 127) x = '.';
58             
59             if (i+j >= len) break;
60             DEBUG(4, ("%c", x));
61           }
62         
63         DEBUG(4, (" hex ", i));
64         
65         for (j = 0; j < 16; j++)
66           {
67             if (i+j >= len) break;
68             DEBUG(4, (" %02x", outbuf[i+j]));
69           }
70         
71         DEBUG(4, ("\n"));
72       }
73     
74 }
75
76
77 /***************************************************************************
78   updates the unique transaction identifier
79   **************************************************************************/
80 static void update_name_trn_id(void)
81 {
82   if (!name_trn_id)
83   {
84     name_trn_id = (time(NULL)%(unsigned)0x7FFF) + (getpid()%(unsigned)100);
85   }
86   name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
87 }
88
89
90 /****************************************************************************
91   initiate a netbios packet
92   ****************************************************************************/
93 void initiate_netbios_packet(uint16 *id,
94                                 int fd,int quest_type,char *name,int name_type,
95                             int nb_flags,BOOL bcast,BOOL recurse,
96                             struct in_addr to_ip)
97 {
98   struct packet_struct p;
99   struct nmb_packet *nmb = &p.packet.nmb;
100   struct res_rec additional_rec;
101   char *packet_type = "unknown";
102   int opcode = -1;
103
104   if (!id) return;
105
106   if (quest_type == NMB_STATUS) { packet_type = "nmb_status"; opcode = 0; }
107   if (quest_type == NMB_QUERY ) { packet_type = "nmb_query"; opcode = 0; }
108   if (quest_type == NMB_REG   ) { packet_type = "nmb_reg"; opcode = 5; }
109   if (quest_type == NMB_REG_REFRESH ) { packet_type = "nmb_reg_refresh"; opcode = 9; }
110   if (quest_type == NMB_REL   ) { packet_type = "nmb_rel"; opcode = 6; }
111   
112   DEBUG(4,("initiating netbios packet: %s %s(%x) (bcast=%s) %s\n",
113            packet_type, name, name_type, BOOLSTR(bcast), inet_ntoa(to_ip)));
114
115   if (opcode == -1) return;
116
117   bzero((char *)&p,sizeof(p));
118
119   if (*id == 0xffff) {
120     update_name_trn_id();
121     *id = name_trn_id; /* allow resending with same id */
122   }
123
124   nmb->header.name_trn_id = *id;
125   nmb->header.opcode = opcode;
126   nmb->header.response = False;
127
128   nmb->header.nm_flags.bcast = bcast;
129   nmb->header.nm_flags.recursion_available = False;
130   nmb->header.nm_flags.recursion_desired = recurse;
131   nmb->header.nm_flags.trunc = False;
132   nmb->header.nm_flags.authoritative = False;
133
134   nmb->header.rcode = 0;
135   nmb->header.qdcount = 1;
136   nmb->header.ancount = 0;
137   nmb->header.nscount = 0;
138   nmb->header.arcount = (quest_type==NMB_REG || 
139                          quest_type==NMB_REL ||
140                          quest_type==NMB_REG_REFRESH) ? 1 : 0;
141   
142   make_nmb_name(&nmb->question.question_name,name,name_type,scope);
143   
144   nmb->question.question_type = quest_type;
145   nmb->question.question_class = 0x1;
146   
147   if (quest_type == NMB_REG ||
148       quest_type == NMB_REG_REFRESH ||
149       quest_type == NMB_REL)
150     {
151       nmb->additional = &additional_rec;
152       bzero((char *)nmb->additional,sizeof(*nmb->additional));
153       
154       nmb->additional->rr_name  = nmb->question.question_name;
155       nmb->additional->rr_type  = nmb->question.question_type;
156       nmb->additional->rr_class = nmb->question.question_class;
157       
158       if (quest_type == NMB_REG || quest_type == NMB_REG_REFRESH)
159         nmb->additional->ttl = lp_max_ttl();
160       else
161         nmb->additional->ttl = 0;
162       nmb->additional->rdlength = 6;
163       nmb->additional->rdata[0] = nb_flags;
164       putip(&nmb->additional->rdata[2],(char *)iface_ip(to_ip));
165     }
166   
167   p.ip = to_ip;
168   p.port = NMB_PORT;
169   p.fd = fd;
170   p.timestamp = time(NULL);
171   p.packet_type = NMB_PACKET;
172   
173   if (!send_packet(&p)) {
174     DEBUG(3,("send_packet to %s %d failed\n",inet_ntoa(p.ip),p.port));
175     *id = 0xffff;
176   }
177   
178   return;
179 }
180
181
182 /****************************************************************************
183   reply to a netbios name packet 
184   ****************************************************************************/
185 void reply_netbios_packet(struct packet_struct *p1,int trn_id,
186                                 int rcode, int rcv_code, int opcode, BOOL recurse,
187                                 struct nmb_name *rr_name,int rr_type,int rr_class,int ttl,
188                                 char *data,int len)
189 {
190   struct packet_struct p;
191   struct nmb_packet *nmb = &p.packet.nmb;
192   struct res_rec answers;
193   char *packet_type = "unknown";
194   BOOL recursion_desired = False;
195   
196   p = *p1;
197
198   switch (rcv_code)
199   {
200     case NMB_STATUS:
201         {
202       packet_type = "nmb_status";
203       recursion_desired = True;
204       break;
205     }
206     case NMB_QUERY:
207         {
208       packet_type = "nmb_query";
209       recursion_desired = True;
210       break;
211     }
212     case NMB_REG:
213         {
214       packet_type = "nmb_reg";
215       recursion_desired = True;
216       break;
217     }
218     case NMB_REL:
219         {
220       packet_type = "nmb_rel";
221       recursion_desired = False;
222       break;
223     }
224     case NMB_WAIT_ACK:
225         {
226       packet_type = "nmb_wack";
227       recursion_desired = False;
228       break;
229     }
230     default:
231     {
232       DEBUG(1,("replying netbios packet: %s %s\n",
233                     packet_type, namestr(rr_name), inet_ntoa(p.ip)));
234
235       return;
236     }
237   }
238
239   DEBUG(4,("replying netbios packet: %s %s\n",
240            packet_type, namestr(rr_name), inet_ntoa(p.ip)));
241
242   nmb->header.name_trn_id = trn_id;
243   nmb->header.opcode = opcode;
244   nmb->header.response = True;
245   nmb->header.nm_flags.bcast = False;
246   nmb->header.nm_flags.recursion_available = recurse;
247   nmb->header.nm_flags.recursion_desired = recursion_desired;
248   nmb->header.nm_flags.trunc = False;
249   nmb->header.nm_flags.authoritative = True;
250   
251   nmb->header.qdcount = 0;
252   nmb->header.ancount = 1;
253   nmb->header.nscount = 0;
254   nmb->header.arcount = 0;
255   nmb->header.rcode = rcode;
256   
257   bzero((char*)&nmb->question,sizeof(nmb->question));
258   
259   nmb->answers = &answers;
260   bzero((char*)nmb->answers,sizeof(*nmb->answers));
261   
262   nmb->answers->rr_name  = *rr_name;
263   nmb->answers->rr_type  = rr_type;
264   nmb->answers->rr_class = rr_class;
265   nmb->answers->ttl      = ttl;
266   
267   if (data && len)
268     {
269       nmb->answers->rdlength = len;
270       memcpy(nmb->answers->rdata, data, len);
271     }
272   
273   p.packet_type = NMB_PACKET;
274   
275   debug_nmb_packet(&p);
276   
277   send_packet(&p);
278 }
279
280
281 /*******************************************************************
282   the global packet linked-list. incoming entries are added to the
283   end of this list.  it is supposed to remain fairly short so we
284   won't bother with an end pointer.
285   ******************************************************************/
286 static struct packet_struct *packet_queue = NULL;
287
288 /*******************************************************************
289   queue a packet into the packet queue
290   ******************************************************************/
291 void queue_packet(struct packet_struct *packet)
292 {
293   struct packet_struct *p;
294
295   if (!packet_queue) {
296     packet->prev = NULL;
297     packet->next = NULL;
298     packet_queue = packet;
299     return;
300   }
301   
302   /* find the bottom */
303   for (p=packet_queue;p->next;p=p->next) ;
304
305   p->next = packet;
306   packet->next = NULL;
307   packet->prev = p;
308 }
309
310 /****************************************************************************
311   determine if a packet is for us. Note that to have any chance of
312   being efficient we need to drop as many packets as possible at this
313   stage as subsequent processing is expensive. 
314
315   We also must make absolutely sure we don't tread on another machines
316   property by answering a packet that is not for us.
317   ****************************************************************************/
318 static BOOL listening(struct packet_struct *p,struct nmb_name *n)
319 {
320   struct subnet_record *d;
321   struct name_record *n1;
322
323   d = find_subnet(p->ip);
324   
325   n1 = find_name_search(&d,n,FIND_LOCAL|FIND_WINS|FIND_SELF,p->ip);
326
327   return (n1 != NULL);
328 }
329
330
331 /****************************************************************************
332   process udp 138 datagrams
333   ****************************************************************************/
334 static void process_dgram(struct packet_struct *p)
335 {
336   char *buf;
337   char *buf2;
338   int len;
339   struct dgram_packet *dgram = &p->packet.dgram;
340
341   /* if we aren't listening to the destination name then ignore the packet */
342   if (!listening(p,&dgram->dest_name))
343     return;
344
345
346   if (dgram->header.msg_type != 0x10 &&
347       dgram->header.msg_type != 0x11 &&
348       dgram->header.msg_type != 0x12) {
349     /* don't process error packets etc yet */
350     return;
351   }
352
353   buf = &dgram->data[0];
354   buf -= 4; /* XXXX for the pseudo tcp length - 
355                someday I need to get rid of this */
356
357   if (CVAL(buf,smb_com) != SMBtrans) return;
358
359   len = SVAL(buf,smb_vwv11);
360   buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
361
362   DEBUG(4,("datagram from %s to %s for %s of type %d len=%d\n",
363            namestr(&dgram->source_name),namestr(&dgram->dest_name),
364            smb_buf(buf),CVAL(buf2,0),len));
365
366  
367   if (len <= 0) return;
368
369    /* datagram packet received for the browser mailslot */
370    if (strequal(smb_buf(buf),BROWSE_MAILSLOT)) {
371      process_browse_packet(p,buf2,len);
372      return;
373    }
374
375    /* datagram packet received for the domain log on mailslot */
376    if (strequal(smb_buf(buf),NET_LOGON_MAILSLOT)) {
377      process_logon_packet(p,buf2,len);
378      return;
379    }
380 }
381
382 /****************************************************************************
383   process a nmb packet
384   ****************************************************************************/
385 static void process_nmb(struct packet_struct *p)
386 {
387   struct nmb_packet *nmb = &p->packet.nmb;
388
389   debug_nmb_packet(p);
390
391   switch (nmb->header.opcode) 
392   {
393     case 8: /* what is this?? */
394     case NMB_REG:
395     case NMB_REG_REFRESH:
396     {
397         if (nmb->header.response)
398         {
399           if (nmb->header.ancount ==0) break;
400           response_netbios_packet(p); /* response to registration dealt 
401                                          with here */
402         }
403         else
404         {
405           if (nmb->header.qdcount==0 || nmb->header.arcount==0) break;
406           reply_name_reg(p);
407         }
408         break;
409     }
410       
411     case 0:
412     {
413           if (nmb->header.response)
414           {
415             switch (nmb->question.question_type)
416               {
417               case 0x0:
418                 {
419                   response_netbios_packet(p);
420                   break;
421                 }
422               }
423             return;
424           }
425       else if (nmb->header.qdcount>0) 
426           {
427             switch (nmb->question.question_type)
428               {
429               case NMB_QUERY:
430                 {
431                   reply_name_query(p);
432                   break;
433                 }
434               case NMB_STATUS:
435                 {
436                   reply_name_status(p);
437                   break;
438                 }
439               }
440             return;
441           }
442         break;
443       }
444       
445     case NMB_REL:
446     {
447         if (nmb->header.response)
448         {
449           if (nmb->header.ancount ==0) break;
450           response_netbios_packet(p); /* response to release dealt 
451                                          with here */
452         }
453         else
454         {
455           if (nmb->header.qdcount==0 || nmb->header.arcount==0) break;
456           reply_name_release(p);
457         }
458       break;
459     }
460   }
461 }
462
463
464 /*******************************************************************
465   run elements off the packet queue till its empty
466   ******************************************************************/
467 void run_packet_queue()
468 {
469   struct packet_struct *p;
470
471   while ((p=packet_queue))
472     {
473       switch (p->packet_type)
474         {
475         case NMB_PACKET:
476           process_nmb(p);
477           break;
478           
479         case DGRAM_PACKET:
480           process_dgram(p);
481           break;
482         }
483       
484       packet_queue = packet_queue->next;
485       if (packet_queue) packet_queue->prev = NULL;
486       free_packet(p);
487     }
488 }
489
490 /****************************************************************************
491   listens for NMB or DGRAM packets, and queues them
492   ***************************************************************************/
493 void listen_for_packets(BOOL run_election)
494 {
495   fd_set fds;
496   int selrtn;
497   struct timeval timeout;
498
499 try_again:
500
501   FD_ZERO(&fds);
502   FD_SET(ClientNMB,&fds);
503   FD_SET(ClientDGRAM,&fds);
504
505   /* during elections and when expecting a netbios response packet we
506      need to send election packets at tighter intervals 
507
508      ideally it needs to be the interval (in ms) between time now and
509      the time we are expecting the next netbios packet */
510
511   timeout.tv_sec = (run_election||num_response_packets) ? 1 : NMBD_SELECT_LOOP;
512   timeout.tv_usec = 0;
513
514   selrtn = sys_select(&fds,&timeout);
515
516   if (FD_ISSET(ClientNMB,&fds))
517     {
518       struct packet_struct *packet = read_packet(ClientNMB, NMB_PACKET);
519       if (packet) {
520         if (ismyip(packet->ip) &&
521             (packet->port == NMB_PORT || packet->port == DGRAM_PORT)) {
522           DEBUG(7,("discarding own packet from %s:%d\n",
523                    inet_ntoa(packet->ip),packet->port));          
524           free_packet(packet);
525           goto try_again;
526         } else {
527           queue_packet(packet);
528         }
529       }
530     }
531
532   if (FD_ISSET(ClientDGRAM,&fds))
533     {
534       struct packet_struct *packet = read_packet(ClientDGRAM, DGRAM_PACKET);
535       if (packet) {
536         if (ismyip(packet->ip) &&
537               (packet->port == NMB_PORT || packet->port == DGRAM_PORT)) {
538           DEBUG(7,("discarding own packet from %s:%d\n",
539                    inet_ntoa(packet->ip),packet->port));          
540           free_packet(packet);
541           goto try_again;
542         } else {
543           queue_packet(packet);
544         }
545       }
546     }
547 }
548
549
550
551 /****************************************************************************
552   construct and send a netbios DGRAM
553
554   Note that this currently sends all answers to port 138. thats the
555   wrong things to do! I should send to the requestors port. XXX
556   **************************************************************************/
557 BOOL send_mailslot_reply(char *mailslot,int fd,char *buf,int len,char *srcname,
558                          char *dstname,int src_type,int dest_type,
559                          struct in_addr dest_ip,struct in_addr src_ip)
560 {
561   struct packet_struct p;
562   struct dgram_packet *dgram = &p.packet.dgram;
563   struct in_addr wins_ip = ipgrp;
564   char *ptr,*p2;
565   char tmp[4];
566
567   /* ha ha. no. do NOT send packets to 255.255.255.255: it's a pseudo address */
568   if (ip_equal(wins_ip, dest_ip)) return False;
569
570   bzero((char *)&p,sizeof(p));
571
572   update_name_trn_id();
573
574   dgram->header.msg_type = 0x11; /* DIRECT GROUP DATAGRAM */
575   dgram->header.flags.node_type = M_NODE;
576   dgram->header.flags.first = True;
577   dgram->header.flags.more = False;
578   dgram->header.dgm_id = name_trn_id;
579   dgram->header.source_ip = src_ip;
580   dgram->header.source_port = DGRAM_PORT;
581   dgram->header.dgm_length = 0; /* let build_dgram() handle this */
582   dgram->header.packet_offset = 0;
583   
584   make_nmb_name(&dgram->source_name,srcname,src_type,scope);
585   make_nmb_name(&dgram->dest_name,dstname,dest_type,scope);
586
587   ptr = &dgram->data[0];
588
589   /* now setup the smb part */
590   ptr -= 4; /* XXX ugliness because of handling of tcp SMB length */
591   memcpy(tmp,ptr,4);
592   set_message(ptr,17,17 + len,True);
593   memcpy(ptr,tmp,4);
594
595   CVAL(ptr,smb_com) = SMBtrans;
596   SSVAL(ptr,smb_vwv1,len);
597   SSVAL(ptr,smb_vwv11,len);
598   SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
599   SSVAL(ptr,smb_vwv13,3);
600   SSVAL(ptr,smb_vwv14,1);
601   SSVAL(ptr,smb_vwv15,1);
602   SSVAL(ptr,smb_vwv16,2);
603   p2 = smb_buf(ptr);
604   strcpy(p2,mailslot);
605   p2 = skip_string(p2,1);
606
607   memcpy(p2,buf,len);
608   p2 += len;
609
610   dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length */
611
612   p.ip = dest_ip;
613   p.port = DGRAM_PORT;
614   p.fd = ClientDGRAM;
615   p.timestamp = time(NULL);
616   p.packet_type = DGRAM_PACKET;
617
618   DEBUG(4,("send mailslot %s from %s %s", mailslot,
619                     inet_ntoa(src_ip),namestr(&dgram->source_name)));
620   DEBUG(4,("to %s %s\n", inet_ntoa(dest_ip),namestr(&dgram->dest_name)));
621
622   return(send_packet(&p));
623 }