fixed the freeze on logout bug. The fix has several parts:
[Samba.git] / source / namepacket.c
blob4a9f586a762d29b5cad0c04da88d10f7f58e54cf
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;
40 extern struct in_addr loopback_ip;
42 static uint16 name_trn_id=0;
45 /***************************************************************************
46 updates the unique transaction identifier
47 **************************************************************************/
48 void debug_browse_data(char *outbuf, int len)
50 int i,j;
51 for (i = 0; i < len; i+= 16)
53 DEBUG(4, ("%3x char ", i));
55 for (j = 0; j < 16; j++)
57 unsigned char x = outbuf[i+j];
58 if (x < 32 || x > 127) x = '.';
60 if (i+j >= len) break;
61 DEBUG(4, ("%c", x));
64 DEBUG(4, (" hex ", i));
66 for (j = 0; j < 16; j++)
68 if (i+j >= len) break;
69 DEBUG(4, (" %02x", (unsigned char)outbuf[i+j]));
72 DEBUG(4, ("\n"));
78 /***************************************************************************
79 updates the unique transaction identifier
80 **************************************************************************/
81 static void update_name_trn_id(void)
83 if (!name_trn_id)
85 name_trn_id = (time(NULL)%(unsigned)0x7FFF) + (getpid()%(unsigned)100);
87 name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
91 /****************************************************************************
92 initiate a netbios packet
93 ****************************************************************************/
94 void initiate_netbios_packet(uint16 *id,
95 int fd,int quest_type,char *name,int name_type,
96 int nb_flags,BOOL bcast,BOOL recurse,
97 struct in_addr to_ip)
99 struct packet_struct p;
100 struct nmb_packet *nmb = &p.packet.nmb;
101 struct res_rec additional_rec;
102 char *packet_type = "unknown";
103 int opcode = -1;
105 if (!id) return;
107 if (quest_type == NMB_STATUS) { packet_type = "nmb_status"; opcode = 0; }
108 if (quest_type == NMB_QUERY ) { packet_type = "nmb_query"; opcode = 0; }
109 if (quest_type == NMB_REG ) { packet_type = "nmb_reg"; opcode = 5; }
110 if (quest_type == NMB_REG_REFRESH ) { packet_type = "nmb_reg_refresh"; opcode = 9; }
111 if (quest_type == NMB_REL ) { packet_type = "nmb_rel"; opcode = 6; }
113 DEBUG(4,("initiating netbios packet: %s %s(%x) (bcast=%s) %s\n",
114 packet_type, name, name_type, BOOLSTR(bcast), inet_ntoa(to_ip)));
116 if (opcode == -1) return;
118 bzero((char *)&p,sizeof(p));
120 if (*id == 0xffff) {
121 update_name_trn_id();
122 *id = name_trn_id; /* allow resending with same id */
125 nmb->header.name_trn_id = *id;
126 nmb->header.opcode = opcode;
127 nmb->header.response = False;
129 nmb->header.nm_flags.bcast = bcast;
130 nmb->header.nm_flags.recursion_available = False;
131 nmb->header.nm_flags.recursion_desired = recurse;
132 nmb->header.nm_flags.trunc = False;
133 nmb->header.nm_flags.authoritative = False;
135 nmb->header.rcode = 0;
136 nmb->header.qdcount = 1;
137 nmb->header.ancount = 0;
138 nmb->header.nscount = 0;
139 nmb->header.arcount = (quest_type==NMB_REG ||
140 quest_type==NMB_REL ||
141 quest_type==NMB_REG_REFRESH) ? 1 : 0;
143 make_nmb_name(&nmb->question.question_name,name,name_type,scope);
145 nmb->question.question_type = quest_type == NMB_STATUS ? 0x21 : 0x20;
146 nmb->question.question_class = 0x1;
148 if (quest_type == NMB_REG ||
149 quest_type == NMB_REG_REFRESH ||
150 quest_type == NMB_REL)
152 nmb->additional = &additional_rec;
153 bzero((char *)nmb->additional,sizeof(*nmb->additional));
155 nmb->additional->rr_name = nmb->question.question_name;
156 nmb->additional->rr_type = 0x20;
157 nmb->additional->rr_class = 0x1;
159 if (quest_type == NMB_REG || quest_type == NMB_REG_REFRESH)
160 nmb->additional->ttl = lp_max_ttl();
161 else
162 nmb->additional->ttl = 0;
164 nmb->additional->rdlength = 6;
165 nmb->additional->rdata[0] = nb_flags;
166 putip(&nmb->additional->rdata[2],(char *)iface_ip(to_ip));
169 p.ip = to_ip;
170 p.port = NMB_PORT;
171 p.fd = fd;
172 p.timestamp = time(NULL);
173 p.packet_type = NMB_PACKET;
175 debug_nmb_packet(&p);
177 if (!send_packet(&p)) {
178 DEBUG(3,("send_packet to %s %d failed\n",inet_ntoa(p.ip),p.port));
179 *id = 0xffff;
182 return;
186 /****************************************************************************
187 reply to a netbios name packet. see rfc1002.txt
188 ****************************************************************************/
189 void reply_netbios_packet(struct packet_struct *p1,int trn_id,
190 int rcode, int rcv_code, int opcode,
191 BOOL recursion_available,
192 BOOL recursion_desired,
193 struct nmb_name *rr_name,int rr_type,int rr_class,int ttl,
194 char *data,int len)
196 struct packet_struct p;
197 struct nmb_packet *nmb = &p.packet.nmb;
198 struct res_rec answers;
199 char *packet_type = "unknown";
201 p = *p1;
203 switch (rcv_code)
205 case NMB_STATUS:
207 packet_type = "nmb_status";
208 break;
210 case NMB_QUERY:
212 packet_type = "nmb_query";
213 break;
215 case NMB_REG:
217 packet_type = "nmb_reg";
218 break;
220 case NMB_REL:
222 packet_type = "nmb_rel";
223 break;
225 case NMB_WAIT_ACK:
227 packet_type = "nmb_wack";
228 break;
230 default:
232 DEBUG(1,("replying netbios packet: %s %s %s\n",
233 packet_type, namestr(rr_name), inet_ntoa(p.ip)));
235 return;
239 DEBUG(4,("replying netbios packet: %s %s %s\n",
240 packet_type, namestr(rr_name), inet_ntoa(p.ip)));
242 nmb->header.name_trn_id = trn_id;
243 nmb->header.opcode = opcode;
244 nmb->header.response = True;
245 nmb->header.nm_flags.bcast = False;
246 nmb->header.nm_flags.recursion_available = recursion_available;
247 nmb->header.nm_flags.recursion_desired = recursion_desired;
248 nmb->header.nm_flags.trunc = False;
249 nmb->header.nm_flags.authoritative = True;
251 nmb->header.qdcount = 0;
252 nmb->header.ancount = 1;
253 nmb->header.nscount = 0;
254 nmb->header.arcount = 0;
255 nmb->header.rcode = rcode;
257 bzero((char*)&nmb->question,sizeof(nmb->question));
259 nmb->answers = &answers;
260 bzero((char*)nmb->answers,sizeof(*nmb->answers));
262 nmb->answers->rr_name = *rr_name;
263 nmb->answers->rr_type = rr_type;
264 nmb->answers->rr_class = rr_class;
265 nmb->answers->ttl = ttl;
267 if (data && len)
269 nmb->answers->rdlength = len;
270 memcpy(nmb->answers->rdata, data, len);
273 p.packet_type = NMB_PACKET;
275 debug_nmb_packet(&p);
277 send_packet(&p);
281 /*******************************************************************
282 the global packet linked-list. incoming entries are added to the
283 end of this list. it is supposed to remain fairly short so we
284 won't bother with an end pointer.
285 ******************************************************************/
286 static struct packet_struct *packet_queue = NULL;
288 /*******************************************************************
289 queue a packet into the packet queue
290 ******************************************************************/
291 void queue_packet(struct packet_struct *packet)
293 struct packet_struct *p;
295 if (!packet_queue) {
296 packet->prev = NULL;
297 packet->next = NULL;
298 packet_queue = packet;
299 return;
302 /* find the bottom */
303 for (p=packet_queue;p->next;p=p->next) ;
305 p->next = packet;
306 packet->next = NULL;
307 packet->prev = p;
310 /****************************************************************************
311 determine if a packet is for us. Note that to have any chance of
312 being efficient we need to drop as many packets as possible at this
313 stage as subsequent processing is expensive.
315 We also must make absolutely sure we don't tread on another machines
316 property by answering a packet that is not for us.
317 ****************************************************************************/
318 static BOOL listening(struct packet_struct *p,struct nmb_name *n)
320 struct subnet_record *d;
321 struct name_record *n1;
323 /* We explicitly don't search WINS here - this will be done
324 in find_name_search if it was a packet from a non-local subnet. */
325 d = find_subnet(p->ip);
327 n1 = find_name_search(&d,n,FIND_LOCAL|FIND_WINS|FIND_SELF,p->ip);
329 return (n1 != NULL);
333 /****************************************************************************
334 process udp 138 datagrams
335 ****************************************************************************/
336 static void process_dgram(struct packet_struct *p)
338 char *buf;
339 char *buf2;
340 int len;
341 struct dgram_packet *dgram = &p->packet.dgram;
343 /* if we aren't listening to the destination name then ignore the packet */
344 if (!listening(p,&dgram->dest_name))
346 DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s(%x) from %s\n",
347 dgram->dest_name.name, dgram->dest_name.name_type, inet_ntoa(p->ip)));
348 return;
351 if (dgram->header.msg_type != 0x10 &&
352 dgram->header.msg_type != 0x11 &&
353 dgram->header.msg_type != 0x12)
355 /* don't process error packets etc yet */
356 DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s(%d) from %s as it is \
357 an error packet of type %x\n",
358 dgram->dest_name.name, dgram->dest_name.name_type,
359 inet_ntoa(p->ip), dgram->header.msg_type));
360 return;
363 buf = &dgram->data[0];
364 buf -= 4; /* XXXX for the pseudo tcp length -
365 someday I need to get rid of this */
367 if (CVAL(buf,smb_com) != SMBtrans) return;
369 len = SVAL(buf,smb_vwv11);
370 buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
372 DEBUG(4,("process_dgram: datagram from %s to %s for %s of type %d len=%d\n",
373 namestr(&dgram->source_name),namestr(&dgram->dest_name),
374 smb_buf(buf),CVAL(buf2,0),len));
377 if (len <= 0) return;
379 /* datagram packet received for the browser mailslot */
380 if (strequal(smb_buf(buf),BROWSE_MAILSLOT)) {
381 process_browse_packet(p,buf2,len);
382 return;
385 /* datagram packet received for the domain log on mailslot */
386 if (strequal(smb_buf(buf),NET_LOGON_MAILSLOT)) {
387 process_logon_packet(p,buf2,len);
388 return;
391 /* datagram packet received for the NT domain log on mailslot */
392 if (strequal(smb_buf(buf),NT_LOGON_MAILSLOT)) {
393 process_logon_packet(p,buf2,len);
394 return;
398 /****************************************************************************
399 process a nmb packet
400 ****************************************************************************/
401 static void process_nmb(struct packet_struct *p)
403 struct nmb_packet *nmb = &p->packet.nmb;
405 debug_nmb_packet(p);
407 switch (nmb->header.opcode)
409 case 8: /* what is this?? */
410 case NMB_REG:
411 case NMB_REG_REFRESH:
413 if (nmb->header.response)
415 if (nmb->header.ancount ==0) break;
416 response_netbios_packet(p); /* response to registration dealt
417 with here */
419 else
421 if (nmb->header.qdcount==0 || nmb->header.arcount==0) break;
422 reply_name_reg(p);
424 break;
427 case 0:
429 if (nmb->header.response)
431 switch (nmb->question.question_type)
433 case 0x0:
435 response_netbios_packet(p);
436 break;
439 return;
441 else if (nmb->header.qdcount>0)
443 switch (nmb->question.question_type)
445 case NMB_QUERY:
447 reply_name_query(p);
448 break;
450 case NMB_STATUS:
452 reply_name_status(p);
453 break;
456 return;
458 break;
461 case NMB_REL:
463 if (nmb->header.response)
465 if (nmb->header.ancount ==0) break;
466 response_netbios_packet(p); /* response to release dealt
467 with here */
469 else
471 if (nmb->header.qdcount==0 || nmb->header.arcount==0) break;
472 reply_name_release(p);
474 break;
480 /*******************************************************************
481 run elements off the packet queue till its empty
482 ******************************************************************/
483 void run_packet_queue()
485 struct packet_struct *p;
487 while ((p=packet_queue))
489 switch (p->packet_type)
491 case NMB_PACKET:
492 process_nmb(p);
493 break;
495 case DGRAM_PACKET:
496 process_dgram(p);
497 break;
500 packet_queue = packet_queue->next;
501 if (packet_queue) packet_queue->prev = NULL;
502 free_packet(p);
506 /****************************************************************************
507 listens for NMB or DGRAM packets, and queues them
508 ***************************************************************************/
509 void listen_for_packets(BOOL run_election)
511 fd_set fds;
512 int selrtn;
513 struct timeval timeout;
515 FD_ZERO(&fds);
516 FD_SET(ClientNMB,&fds);
517 FD_SET(ClientDGRAM,&fds);
519 /* during elections and when expecting a netbios response packet we
520 need to send election packets at tighter intervals
522 ideally it needs to be the interval (in ms) between time now and
523 the time we are expecting the next netbios packet */
525 timeout.tv_sec = (run_election||num_response_packets) ? 1:NMBD_SELECT_LOOP;
526 timeout.tv_usec = 0;
528 /* We can only take term signals when we are in the select. */
529 BlockSignals(False, SIGTERM);
530 selrtn = sys_select(&fds,&timeout);
531 BlockSignals(True, SIGTERM);
533 if (FD_ISSET(ClientNMB,&fds))
535 struct packet_struct *packet = read_packet(ClientNMB, NMB_PACKET);
536 if (packet)
538 if ((ip_equal(loopback_ip, packet->ip) ||
539 ismyip(packet->ip)) &&
540 packet->port == NMB_PORT)
542 DEBUG(7,("discarding own packet from %s:%d\n",
543 inet_ntoa(packet->ip),packet->port));
544 free_packet(packet);
546 else
548 queue_packet(packet);
553 if (FD_ISSET(ClientDGRAM,&fds))
555 struct packet_struct *packet = read_packet(ClientDGRAM, DGRAM_PACKET);
556 if (packet)
558 if ((ip_equal(loopback_ip, packet->ip) ||
559 ismyip(packet->ip)) &&
560 packet->port == DGRAM_PORT)
562 DEBUG(7,("discarding own packet from %s:%d\n",
563 inet_ntoa(packet->ip),packet->port));
564 free_packet(packet);
566 else
568 queue_packet(packet);
576 /****************************************************************************
577 construct and send a netbios DGRAM
579 Note that this currently sends all answers to port 138. thats the
580 wrong things to do! I should send to the requestors port. XXX
581 **************************************************************************/
582 BOOL send_mailslot_reply(BOOL unique, char *mailslot,int fd,char *buf,int len,char *srcname,
583 char *dstname,int src_type,int dest_type,
584 struct in_addr dest_ip,struct in_addr src_ip)
586 struct packet_struct p;
587 struct dgram_packet *dgram = &p.packet.dgram;
588 char *ptr,*p2;
589 char tmp[4];
591 /* ha ha. no. do NOT send packets to 255.255.255.255: it's a pseudo address */
592 if (ip_equal(wins_ip, dest_ip)) return False;
594 bzero((char *)&p,sizeof(p));
596 update_name_trn_id();
598 /* DIRECT GROUP or UNIQUE datagram */
599 dgram->header.msg_type = unique ? 0x10 : 0x11;
600 dgram->header.flags.node_type = M_NODE;
601 dgram->header.flags.first = True;
602 dgram->header.flags.more = False;
603 dgram->header.dgm_id = name_trn_id;
604 dgram->header.source_ip = src_ip;
605 dgram->header.source_port = DGRAM_PORT;
606 dgram->header.dgm_length = 0; /* let build_dgram() handle this */
607 dgram->header.packet_offset = 0;
609 make_nmb_name(&dgram->source_name,srcname,src_type,scope);
610 make_nmb_name(&dgram->dest_name,dstname,dest_type,scope);
612 ptr = &dgram->data[0];
614 /* now setup the smb part */
615 ptr -= 4; /* XXX ugliness because of handling of tcp SMB length */
616 memcpy(tmp,ptr,4);
617 set_message(ptr,17,17 + len,True);
618 memcpy(ptr,tmp,4);
620 CVAL(ptr,smb_com) = SMBtrans;
621 SSVAL(ptr,smb_vwv1,len);
622 SSVAL(ptr,smb_vwv11,len);
623 SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
624 SSVAL(ptr,smb_vwv13,3);
625 SSVAL(ptr,smb_vwv14,1);
626 SSVAL(ptr,smb_vwv15,1);
627 SSVAL(ptr,smb_vwv16,2);
628 p2 = smb_buf(ptr);
629 strcpy(p2,mailslot);
630 p2 = skip_string(p2,1);
632 memcpy(p2,buf,len);
633 p2 += len;
635 dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length */
637 p.ip = dest_ip;
638 p.port = DGRAM_PORT;
639 p.fd = ClientDGRAM;
640 p.timestamp = time(NULL);
641 p.packet_type = DGRAM_PACKET;
643 DEBUG(4,("send mailslot %s from %s %s", mailslot,
644 inet_ntoa(src_ip),namestr(&dgram->source_name)));
645 DEBUG(4,("to %s %s\n", inet_ntoa(dest_ip),namestr(&dgram->dest_name)));
647 return(send_packet(&p));