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