made "hide files" and "veto files" into per-service parameter sections,
[Samba.git] / source / namepacket.c
blob55b525d6c5076c7f4b1f9ce0baf87a541e1a14c3
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
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.
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.
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.
21 Revision History:
23 14 jan 96: lkcl@pires.co.uk
24 added multiple workgroup domain master support
28 #include "includes.h"
30 extern int ClientNMB;
31 extern int ClientDGRAM;
33 extern int DEBUGLEVEL;
35 extern int num_response_packets;
37 BOOL CanRecurse = True;
38 extern pstring scope;
39 extern struct in_addr wins_ip;
41 static uint16 name_trn_id=0;
44 /***************************************************************************
45 updates the unique transaction identifier
46 **************************************************************************/
47 void debug_browse_data(char *outbuf, int len)
49 int i,j;
50 for (i = 0; i < len; i+= 16)
52 DEBUG(4, ("%3x char ", i));
54 for (j = 0; j < 16; j++)
56 unsigned char x = outbuf[i+j];
57 if (x < 32 || x > 127) x = '.';
59 if (i+j >= len) break;
60 DEBUG(4, ("%c", x));
63 DEBUG(4, (" hex ", i));
65 for (j = 0; j < 16; j++)
67 if (i+j >= len) break;
68 DEBUG(4, (" %02x", outbuf[i+j]));
71 DEBUG(4, ("\n"));
77 /***************************************************************************
78 updates the unique transaction identifier
79 **************************************************************************/
80 static void update_name_trn_id(void)
82 if (!name_trn_id)
84 name_trn_id = (time(NULL)%(unsigned)0x7FFF) + (getpid()%(unsigned)100);
86 name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
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)
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;
104 if (!id) return;
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; }
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)));
115 if (opcode == -1) return;
117 bzero((char *)&p,sizeof(p));
119 if (*id == 0xffff) {
120 update_name_trn_id();
121 *id = name_trn_id; /* allow resending with same id */
124 nmb->header.name_trn_id = *id;
125 nmb->header.opcode = opcode;
126 nmb->header.response = False;
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;
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;
142 make_nmb_name(&nmb->question.question_name,name,name_type,scope);
144 nmb->question.question_type = quest_type == NMB_STATUS ? 0x21 : 0x20;
145 nmb->question.question_class = 0x1;
147 if (quest_type == NMB_REG ||
148 quest_type == NMB_REG_REFRESH ||
149 quest_type == NMB_REL)
151 nmb->additional = &additional_rec;
152 bzero((char *)nmb->additional,sizeof(*nmb->additional));
154 nmb->additional->rr_name = nmb->question.question_name;
155 nmb->additional->rr_type = 0x20;
156 nmb->additional->rr_class = 0x1;
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;
163 nmb->additional->rdlength = 6;
164 nmb->additional->rdata[0] = nb_flags;
165 putip(&nmb->additional->rdata[2],(char *)iface_ip(to_ip));
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;
174 debug_nmb_packet(&p);
176 if (!send_packet(&p)) {
177 DEBUG(3,("send_packet to %s %d failed\n",inet_ntoa(p.ip),p.port));
178 *id = 0xffff;
181 return;
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)
193 struct packet_struct p;
194 struct nmb_packet *nmb = &p.packet.nmb;
195 struct res_rec answers;
196 char *packet_type = "unknown";
198 p = *p1;
200 switch (rcv_code)
202 case NMB_STATUS:
204 packet_type = "nmb_status";
205 break;
207 case NMB_QUERY:
209 packet_type = "nmb_query";
210 break;
212 case NMB_REG:
214 packet_type = "nmb_reg";
215 break;
217 case NMB_REL:
219 packet_type = "nmb_rel";
220 break;
222 case NMB_WAIT_ACK:
224 packet_type = "nmb_wack";
225 break;
227 default:
229 DEBUG(1,("replying netbios packet: %s %s\n",
230 packet_type, namestr(rr_name), inet_ntoa(p.ip)));
232 return;
236 DEBUG(4,("replying netbios packet: %s %s\n",
237 packet_type, namestr(rr_name), inet_ntoa(p.ip)));
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;
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;
254 bzero((char*)&nmb->question,sizeof(nmb->question));
256 nmb->answers = &answers;
257 bzero((char*)nmb->answers,sizeof(*nmb->answers));
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;
264 if (data && len)
266 nmb->answers->rdlength = len;
267 memcpy(nmb->answers->rdata, data, len);
270 p.packet_type = NMB_PACKET;
272 debug_nmb_packet(&p);
274 send_packet(&p);
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;
285 /*******************************************************************
286 queue a packet into the packet queue
287 ******************************************************************/
288 void queue_packet(struct packet_struct *packet)
290 struct packet_struct *p;
292 if (!packet_queue) {
293 packet->prev = NULL;
294 packet->next = NULL;
295 packet_queue = packet;
296 return;
299 /* find the bottom */
300 for (p=packet_queue;p->next;p=p->next) ;
302 p->next = packet;
303 packet->next = NULL;
304 packet->prev = p;
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.
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)
317 struct subnet_record *d;
318 struct name_record *n1;
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);
324 n1 = find_name_search(&d,n,FIND_LOCAL|FIND_WINS|FIND_SELF,p->ip);
326 return (n1 != NULL);
330 /****************************************************************************
331 process udp 138 datagrams
332 ****************************************************************************/
333 static void process_dgram(struct packet_struct *p)
335 char *buf;
336 char *buf2;
337 int len;
338 struct dgram_packet *dgram = &p->packet.dgram;
340 /* if we aren't listening to the destination name then ignore the packet */
341 if (!listening(p,&dgram->dest_name))
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;
348 if (dgram->header.msg_type != 0x10 &&
349 dgram->header.msg_type != 0x11 &&
350 dgram->header.msg_type != 0x12)
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;
360 buf = &dgram->data[0];
361 buf -= 4; /* XXXX for the pseudo tcp length -
362 someday I need to get rid of this */
364 if (CVAL(buf,smb_com) != SMBtrans) return;
366 len = SVAL(buf,smb_vwv11);
367 buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
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));
374 if (len <= 0) return;
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;
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;
389 /****************************************************************************
390 process a nmb packet
391 ****************************************************************************/
392 static void process_nmb(struct packet_struct *p)
394 struct nmb_packet *nmb = &p->packet.nmb;
396 debug_nmb_packet(p);
398 switch (nmb->header.opcode)
400 case 8: /* what is this?? */
401 case NMB_REG:
402 case NMB_REG_REFRESH:
404 if (nmb->header.response)
406 if (nmb->header.ancount ==0) break;
407 response_netbios_packet(p); /* response to registration dealt
408 with here */
410 else
412 if (nmb->header.qdcount==0 || nmb->header.arcount==0) break;
413 reply_name_reg(p);
415 break;
418 case 0:
420 if (nmb->header.response)
422 switch (nmb->question.question_type)
424 case 0x0:
426 response_netbios_packet(p);
427 break;
430 return;
432 else if (nmb->header.qdcount>0)
434 switch (nmb->question.question_type)
436 case NMB_QUERY:
438 reply_name_query(p);
439 break;
441 case NMB_STATUS:
443 reply_name_status(p);
444 break;
447 return;
449 break;
452 case NMB_REL:
454 if (nmb->header.response)
456 if (nmb->header.ancount ==0) break;
457 response_netbios_packet(p); /* response to release dealt
458 with here */
460 else
462 if (nmb->header.qdcount==0 || nmb->header.arcount==0) break;
463 reply_name_release(p);
465 break;
471 /*******************************************************************
472 run elements off the packet queue till its empty
473 ******************************************************************/
474 void run_packet_queue()
476 struct packet_struct *p;
478 while ((p=packet_queue))
480 switch (p->packet_type)
482 case NMB_PACKET:
483 process_nmb(p);
484 break;
486 case DGRAM_PACKET:
487 process_dgram(p);
488 break;
491 packet_queue = packet_queue->next;
492 if (packet_queue) packet_queue->prev = NULL;
493 free_packet(p);
497 /****************************************************************************
498 listens for NMB or DGRAM packets, and queues them
499 ***************************************************************************/
500 void listen_for_packets(BOOL run_election)
502 fd_set fds;
503 int selrtn;
504 struct timeval timeout;
506 FD_ZERO(&fds);
507 FD_SET(ClientNMB,&fds);
508 FD_SET(ClientDGRAM,&fds);
510 /* during elections and when expecting a netbios response packet we
511 need to send election packets at tighter intervals
513 ideally it needs to be the interval (in ms) between time now and
514 the time we are expecting the next netbios packet */
516 timeout.tv_sec = (run_election||num_response_packets) ? 1:NMBD_SELECT_LOOP;
517 timeout.tv_usec = 0;
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);
524 if (FD_ISSET(ClientNMB,&fds))
526 struct packet_struct *packet = read_packet(ClientNMB, NMB_PACKET);
527 if (packet)
529 if (ismyip(packet->ip) && packet->port == NMB_PORT)
531 DEBUG(7,("discarding own packet from %s:%d\n",
532 inet_ntoa(packet->ip),packet->port));
533 free_packet(packet);
535 else
537 queue_packet(packet);
542 if (FD_ISSET(ClientDGRAM,&fds))
544 struct packet_struct *packet = read_packet(ClientDGRAM, DGRAM_PACKET);
545 if (packet)
547 if (ismyip(packet->ip) && packet->port == DGRAM_PORT)
549 DEBUG(7,("discarding own packet from %s:%d\n",
550 inet_ntoa(packet->ip),packet->port));
551 free_packet(packet);
553 else
555 queue_packet(packet);
563 /****************************************************************************
564 construct and send a netbios DGRAM
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)
573 struct packet_struct p;
574 struct dgram_packet *dgram = &p.packet.dgram;
575 char *ptr,*p2;
576 char tmp[4];
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;
581 bzero((char *)&p,sizeof(p));
583 update_name_trn_id();
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;
596 make_nmb_name(&dgram->source_name,srcname,src_type,scope);
597 make_nmb_name(&dgram->dest_name,dstname,dest_type,scope);
599 ptr = &dgram->data[0];
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);
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);
619 memcpy(p2,buf,len);
620 p2 += len;
622 dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length */
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;
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)));
634 return(send_packet(&p));