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