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