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