JHT ==> Just tidying up for Release.
[ira/wip.git] / source3 / 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-1997
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 wins_ip;
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 == NMB_STATUS ? 0x21 : 0x20;
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  = 0x20;
156       nmb->additional->rr_class = 0x1;
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
163       nmb->additional->rdlength = 6;
164       nmb->additional->rdata[0] = nb_flags;
165       putip(&nmb->additional->rdata[2],(char *)iface_ip(to_ip));
166   }
167   
168   p.ip = to_ip;
169   p.port = NMB_PORT;
170   p.fd = fd;
171   p.timestamp = time(NULL);
172   p.packet_type = NMB_PACKET;
173   
174   debug_nmb_packet(&p);
175   
176   if (!send_packet(&p)) {
177     DEBUG(3,("send_packet to %s %d failed\n",inet_ntoa(p.ip),p.port));
178     *id = 0xffff;
179   }
180   
181   return;
182 }
183
184
185 /****************************************************************************
186   reply to a netbios name packet 
187   ****************************************************************************/
188 void reply_netbios_packet(struct packet_struct *p1,int trn_id,
189                                 int rcode, int rcv_code, int opcode, BOOL recurse,
190                                 struct nmb_name *rr_name,int rr_type,int rr_class,int ttl,
191                                 char *data,int len)
192 {
193   struct packet_struct p;
194   struct nmb_packet *nmb = &p.packet.nmb;
195   struct res_rec answers;
196   char *packet_type = "unknown";
197   
198   p = *p1;
199
200   switch (rcv_code)
201   {
202     case NMB_STATUS:
203         {
204       packet_type = "nmb_status";
205       break;
206     }
207     case NMB_QUERY:
208         {
209       packet_type = "nmb_query";
210       break;
211     }
212     case NMB_REG:
213         {
214       packet_type = "nmb_reg";
215       break;
216     }
217     case NMB_REL:
218         {
219       packet_type = "nmb_rel";
220       break;
221     }
222     case NMB_WAIT_ACK:
223         {
224       packet_type = "nmb_wack";
225       break;
226     }
227     default:
228     {
229       DEBUG(1,("replying netbios packet: %s %s\n",
230                     packet_type, namestr(rr_name), inet_ntoa(p.ip)));
231
232       return;
233     }
234   }
235
236   DEBUG(4,("replying netbios packet: %s %s\n",
237            packet_type, namestr(rr_name), inet_ntoa(p.ip)));
238
239   nmb->header.name_trn_id = trn_id;
240   nmb->header.opcode = opcode;
241   nmb->header.response = True;
242   nmb->header.nm_flags.bcast = False;
243   nmb->header.nm_flags.recursion_available = (lp_wins_support() ? True : False );
244   nmb->header.nm_flags.recursion_desired = (lp_wins_support() ? recurse : False );
245   nmb->header.nm_flags.trunc = False;
246   nmb->header.nm_flags.authoritative = True;
247   
248   nmb->header.qdcount = 0;
249   nmb->header.ancount = 1;
250   nmb->header.nscount = 0;
251   nmb->header.arcount = 0;
252   nmb->header.rcode = rcode;
253   
254   bzero((char*)&nmb->question,sizeof(nmb->question));
255   
256   nmb->answers = &answers;
257   bzero((char*)nmb->answers,sizeof(*nmb->answers));
258   
259   nmb->answers->rr_name  = *rr_name;
260   nmb->answers->rr_type  = rr_type;
261   nmb->answers->rr_class = rr_class;
262   nmb->answers->ttl      = ttl;
263   
264   if (data && len)
265     {
266       nmb->answers->rdlength = len;
267       memcpy(nmb->answers->rdata, data, len);
268     }
269   
270   p.packet_type = NMB_PACKET;
271   
272   debug_nmb_packet(&p);
273   
274   send_packet(&p);
275 }
276
277
278 /*******************************************************************
279   the global packet linked-list. incoming entries are added to the
280   end of this list.  it is supposed to remain fairly short so we
281   won't bother with an end pointer.
282   ******************************************************************/
283 static struct packet_struct *packet_queue = NULL;
284
285 /*******************************************************************
286   queue a packet into the packet queue
287   ******************************************************************/
288 void queue_packet(struct packet_struct *packet)
289 {
290   struct packet_struct *p;
291
292   if (!packet_queue) {
293     packet->prev = NULL;
294     packet->next = NULL;
295     packet_queue = packet;
296     return;
297   }
298   
299   /* find the bottom */
300   for (p=packet_queue;p->next;p=p->next) ;
301
302   p->next = packet;
303   packet->next = NULL;
304   packet->prev = p;
305 }
306
307 /****************************************************************************
308   determine if a packet is for us. Note that to have any chance of
309   being efficient we need to drop as many packets as possible at this
310   stage as subsequent processing is expensive. 
311
312   We also must make absolutely sure we don't tread on another machines
313   property by answering a packet that is not for us.
314   ****************************************************************************/
315 static BOOL listening(struct packet_struct *p,struct nmb_name *n)
316 {
317   struct subnet_record *d;
318   struct name_record *n1;
319
320   /* We explicitly don't search WINS here - this will be done
321      in find_name_search if it was a packet from a non-local subnet. */
322   d = find_subnet(p->ip);
323
324   n1 = find_name_search(&d,n,FIND_LOCAL|FIND_WINS|FIND_SELF,p->ip);
325
326   return (n1 != NULL);
327 }
328
329
330 /****************************************************************************
331   process udp 138 datagrams
332   ****************************************************************************/
333 static void process_dgram(struct packet_struct *p)
334 {
335   char *buf;
336   char *buf2;
337   int len;
338   struct dgram_packet *dgram = &p->packet.dgram;
339
340   /* if we aren't listening to the destination name then ignore the packet */
341   if (!listening(p,&dgram->dest_name))
342   {
343     DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s(%x) from %s\n",
344            dgram->dest_name.name, dgram->dest_name.name_type, inet_ntoa(p->ip)));
345     return;
346   }
347
348   if (dgram->header.msg_type != 0x10 &&
349       dgram->header.msg_type != 0x11 &&
350       dgram->header.msg_type != 0x12) 
351   {
352     /* don't process error packets etc yet */
353     DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s(%d) from %s as it is \
354            an error packet of type %x\n",
355            dgram->dest_name.name, dgram->dest_name.name_type, 
356            inet_ntoa(p->ip), dgram->header.msg_type));
357     return;
358   }
359
360   buf = &dgram->data[0];
361   buf -= 4; /* XXXX for the pseudo tcp length - 
362                someday I need to get rid of this */
363
364   if (CVAL(buf,smb_com) != SMBtrans) return;
365
366   len = SVAL(buf,smb_vwv11);
367   buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
368
369   DEBUG(4,("process_dgram: datagram from %s to %s for %s of type %d len=%d\n",
370            namestr(&dgram->source_name),namestr(&dgram->dest_name),
371            smb_buf(buf),CVAL(buf2,0),len));
372
373  
374   if (len <= 0) return;
375
376    /* datagram packet received for the browser mailslot */
377    if (strequal(smb_buf(buf),BROWSE_MAILSLOT)) {
378      process_browse_packet(p,buf2,len);
379      return;
380    }
381
382    /* datagram packet received for the domain log on mailslot */
383    if (strequal(smb_buf(buf),NET_LOGON_MAILSLOT)) {
384      process_logon_packet(p,buf2,len);
385      return;
386    }
387 }
388
389 /****************************************************************************
390   process a nmb packet
391   ****************************************************************************/
392 static void process_nmb(struct packet_struct *p)
393 {
394   struct nmb_packet *nmb = &p->packet.nmb;
395
396   debug_nmb_packet(p);
397
398   switch (nmb->header.opcode) 
399   {
400     case 8: /* what is this?? */
401     case NMB_REG:
402     case NMB_REG_REFRESH:
403     {
404         if (nmb->header.response)
405         {
406           if (nmb->header.ancount ==0) break;
407           response_netbios_packet(p); /* response to registration dealt 
408                                          with here */
409         }
410         else
411         {
412           if (nmb->header.qdcount==0 || nmb->header.arcount==0) break;
413           reply_name_reg(p);
414         }
415         break;
416     }
417       
418     case 0:
419     {
420           if (nmb->header.response)
421           {
422             switch (nmb->question.question_type)
423               {
424               case 0x0:
425                 {
426                   response_netbios_packet(p);
427                   break;
428                 }
429               }
430             return;
431           }
432       else if (nmb->header.qdcount>0) 
433           {
434             switch (nmb->question.question_type)
435               {
436               case NMB_QUERY:
437                 {
438                   reply_name_query(p);
439                   break;
440                 }
441               case NMB_STATUS:
442                 {
443                   reply_name_status(p);
444                   break;
445                 }
446               }
447             return;
448           }
449         break;
450       }
451       
452     case NMB_REL:
453     {
454         if (nmb->header.response)
455         {
456           if (nmb->header.ancount ==0) break;
457           response_netbios_packet(p); /* response to release dealt 
458                                          with here */
459         }
460         else
461         {
462           if (nmb->header.qdcount==0 || nmb->header.arcount==0) break;
463           reply_name_release(p);
464         }
465       break;
466     }
467   }
468 }
469
470
471 /*******************************************************************
472   run elements off the packet queue till its empty
473   ******************************************************************/
474 void run_packet_queue()
475 {
476   struct packet_struct *p;
477
478   while ((p=packet_queue))
479     {
480       switch (p->packet_type)
481         {
482         case NMB_PACKET:
483           process_nmb(p);
484           break;
485           
486         case DGRAM_PACKET:
487           process_dgram(p);
488           break;
489         }
490       
491       packet_queue = packet_queue->next;
492       if (packet_queue) packet_queue->prev = NULL;
493       free_packet(p);
494     }
495 }
496
497 /****************************************************************************
498   listens for NMB or DGRAM packets, and queues them
499   ***************************************************************************/
500 void listen_for_packets(BOOL run_election)
501 {
502         fd_set fds;
503         int selrtn;
504         struct timeval timeout;
505
506         FD_ZERO(&fds);
507         FD_SET(ClientNMB,&fds);
508         FD_SET(ClientDGRAM,&fds);
509
510         /* during elections and when expecting a netbios response packet we
511         need to send election packets at tighter intervals 
512
513         ideally it needs to be the interval (in ms) between time now and
514         the time we are expecting the next netbios packet */
515
516         timeout.tv_sec = (run_election||num_response_packets) ? 1:NMBD_SELECT_LOOP;
517         timeout.tv_usec = 0;
518
519         /* We can only take term signals when we are in the select. */
520         BlockSignals(False, SIGTERM);
521         selrtn = sys_select(&fds,&timeout);
522         BlockSignals(True, SIGTERM);
523
524         if (FD_ISSET(ClientNMB,&fds))
525         {
526                 struct packet_struct *packet = read_packet(ClientNMB, NMB_PACKET);
527                 if (packet)
528                 {
529                         if (ismyip(packet->ip) && packet->port == NMB_PORT)
530                         {
531                                 DEBUG(7,("discarding own packet from %s:%d\n",
532                                           inet_ntoa(packet->ip),packet->port));   
533                                 free_packet(packet);
534                         }
535                         else
536                         {
537                                 queue_packet(packet);
538                         }
539                 }
540         }
541
542         if (FD_ISSET(ClientDGRAM,&fds))
543         {
544                 struct packet_struct *packet = read_packet(ClientDGRAM, DGRAM_PACKET);
545                 if (packet)
546                 {
547                         if (ismyip(packet->ip) && packet->port == DGRAM_PORT)
548                         {
549                                 DEBUG(7,("discarding own packet from %s:%d\n",
550                                           inet_ntoa(packet->ip),packet->port));   
551                                 free_packet(packet);
552                         }
553                         else
554                         {
555                                 queue_packet(packet);
556                         }
557                 }
558         }
559 }
560
561
562
563 /****************************************************************************
564   construct and send a netbios DGRAM
565
566   Note that this currently sends all answers to port 138. thats the
567   wrong things to do! I should send to the requestors port. XXX
568   **************************************************************************/
569 BOOL send_mailslot_reply(BOOL unique, char *mailslot,int fd,char *buf,int len,char *srcname,
570                          char *dstname,int src_type,int dest_type,
571                          struct in_addr dest_ip,struct in_addr src_ip)
572 {
573   struct packet_struct p;
574   struct dgram_packet *dgram = &p.packet.dgram;
575   char *ptr,*p2;
576   char tmp[4];
577
578   /* ha ha. no. do NOT send packets to 255.255.255.255: it's a pseudo address */
579   if (ip_equal(wins_ip, dest_ip)) return False;
580
581   bzero((char *)&p,sizeof(p));
582
583   update_name_trn_id();
584
585   /* DIRECT GROUP or UNIQUE datagram */
586   dgram->header.msg_type = unique ? 0x10 : 0x11; 
587   dgram->header.flags.node_type = M_NODE;
588   dgram->header.flags.first = True;
589   dgram->header.flags.more = False;
590   dgram->header.dgm_id = name_trn_id;
591   dgram->header.source_ip = src_ip;
592   dgram->header.source_port = DGRAM_PORT;
593   dgram->header.dgm_length = 0; /* let build_dgram() handle this */
594   dgram->header.packet_offset = 0;
595   
596   make_nmb_name(&dgram->source_name,srcname,src_type,scope);
597   make_nmb_name(&dgram->dest_name,dstname,dest_type,scope);
598
599   ptr = &dgram->data[0];
600
601   /* now setup the smb part */
602   ptr -= 4; /* XXX ugliness because of handling of tcp SMB length */
603   memcpy(tmp,ptr,4);
604   set_message(ptr,17,17 + len,True);
605   memcpy(ptr,tmp,4);
606
607   CVAL(ptr,smb_com) = SMBtrans;
608   SSVAL(ptr,smb_vwv1,len);
609   SSVAL(ptr,smb_vwv11,len);
610   SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
611   SSVAL(ptr,smb_vwv13,3);
612   SSVAL(ptr,smb_vwv14,1);
613   SSVAL(ptr,smb_vwv15,1);
614   SSVAL(ptr,smb_vwv16,2);
615   p2 = smb_buf(ptr);
616   strcpy(p2,mailslot);
617   p2 = skip_string(p2,1);
618
619   memcpy(p2,buf,len);
620   p2 += len;
621
622   dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length */
623
624   p.ip = dest_ip;
625   p.port = DGRAM_PORT;
626   p.fd = ClientDGRAM;
627   p.timestamp = time(NULL);
628   p.packet_type = DGRAM_PACKET;
629
630   DEBUG(4,("send mailslot %s from %s %s", mailslot,
631                     inet_ntoa(src_ip),namestr(&dgram->source_name)));
632   DEBUG(4,("to %s %s\n", inet_ntoa(dest_ip),namestr(&dgram->dest_name)));
633
634   return(send_packet(&p));
635 }