2 Unix SMB/Netbios implementation.
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.
23 14 jan 96: lkcl@pires.co.uk
24 added multiple workgroup domain master support
31 extern int ClientDGRAM;
33 extern int DEBUGLEVEL;
35 extern int num_response_packets;
37 BOOL CanRecurse = True;
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)
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;
63 DEBUG(4, (" hex ", i));
65 for (j = 0; j < 16; j++)
67 if (i+j >= len) break;
68 DEBUG(4, (" %02x", (unsigned char)outbuf[i+j]));
77 /***************************************************************************
78 updates the unique transaction identifier
79 **************************************************************************/
80 static void update_name_trn_id(void)
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,
98 struct packet_struct p;
99 struct nmb_packet *nmb = &p.packet.nmb;
100 struct res_rec additional_rec;
101 char *packet_type = "unknown";
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));
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();
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));
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));
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,
195 struct packet_struct p;
196 struct nmb_packet *nmb = &p.packet.nmb;
197 struct res_rec answers;
198 char *packet_type = "unknown";
206 packet_type = "nmb_status";
211 packet_type = "nmb_query";
216 packet_type = "nmb_reg";
221 packet_type = "nmb_rel";
226 packet_type = "nmb_wack";
231 DEBUG(1,("replying netbios packet: %s %s\n",
232 packet_type, namestr(rr_name), inet_ntoa(p.ip)));
238 DEBUG(4,("replying netbios packet: %s %s\n",
239 packet_type, namestr(rr_name), inet_ntoa(p.ip)));
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;
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;
256 bzero((char*)&nmb->question,sizeof(nmb->question));
258 nmb->answers = &answers;
259 bzero((char*)nmb->answers,sizeof(*nmb->answers));
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;
268 nmb->answers->rdlength = len;
269 memcpy(nmb->answers->rdata, data, len);
272 p.packet_type = NMB_PACKET;
274 debug_nmb_packet(&p);
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;
287 /*******************************************************************
288 queue a packet into the packet queue
289 ******************************************************************/
290 void queue_packet(struct packet_struct *packet)
292 struct packet_struct *p;
297 packet_queue = packet;
301 /* find the bottom */
302 for (p=packet_queue;p->next;p=p->next) ;
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.
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)
319 struct subnet_record *d;
320 struct name_record *n1;
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);
326 n1 = find_name_search(&d,n,FIND_LOCAL|FIND_WINS|FIND_SELF,p->ip);
332 /****************************************************************************
333 process udp 138 datagrams
334 ****************************************************************************/
335 static void process_dgram(struct packet_struct *p)
340 struct dgram_packet *dgram = &p->packet.dgram;
342 /* if we aren't listening to the destination name then ignore the packet */
343 if (!listening(p,&dgram->dest_name))
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)));
350 if (dgram->header.msg_type != 0x10 &&
351 dgram->header.msg_type != 0x11 &&
352 dgram->header.msg_type != 0x12)
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));
362 buf = &dgram->data[0];
363 buf -= 4; /* XXXX for the pseudo tcp length -
364 someday I need to get rid of this */
366 if (CVAL(buf,smb_com) != SMBtrans) return;
368 len = SVAL(buf,smb_vwv11);
369 buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
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));
376 if (len <= 0) return;
378 /* datagram packet received for the browser mailslot */
379 if (strequal(smb_buf(buf),BROWSE_MAILSLOT)) {
380 process_browse_packet(p,buf2,len);
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);
391 /****************************************************************************
393 ****************************************************************************/
394 static void process_nmb(struct packet_struct *p)
396 struct nmb_packet *nmb = &p->packet.nmb;
400 switch (nmb->header.opcode)
402 case 8: /* what is this?? */
404 case NMB_REG_REFRESH:
406 if (nmb->header.response)
408 if (nmb->header.ancount ==0) break;
409 response_netbios_packet(p); /* response to registration dealt
414 if (nmb->header.qdcount==0 || nmb->header.arcount==0) break;
422 if (nmb->header.response)
424 switch (nmb->question.question_type)
428 response_netbios_packet(p);
434 else if (nmb->header.qdcount>0)
436 switch (nmb->question.question_type)
445 reply_name_status(p);
456 if (nmb->header.response)
458 if (nmb->header.ancount ==0) break;
459 response_netbios_packet(p); /* response to release dealt
464 if (nmb->header.qdcount==0 || nmb->header.arcount==0) break;
465 reply_name_release(p);
473 /*******************************************************************
474 run elements off the packet queue till its empty
475 ******************************************************************/
476 void run_packet_queue()
478 struct packet_struct *p;
480 while ((p=packet_queue))
482 switch (p->packet_type)
493 packet_queue = packet_queue->next;
494 if (packet_queue) packet_queue->prev = NULL;
499 /****************************************************************************
500 listens for NMB or DGRAM packets, and queues them
501 ***************************************************************************/
502 void listen_for_packets(BOOL run_election)
506 struct timeval timeout;
509 FD_SET(ClientNMB,&fds);
510 FD_SET(ClientDGRAM,&fds);
512 /* during elections and when expecting a netbios response packet we
513 need to send election packets at tighter intervals
515 ideally it needs to be the interval (in ms) between time now and
516 the time we are expecting the next netbios packet */
518 timeout.tv_sec = (run_election||num_response_packets) ? 1:NMBD_SELECT_LOOP;
521 /* We can only take term signals when we are in the select. */
522 BlockSignals(False, SIGTERM);
523 selrtn = sys_select(&fds,&timeout);
524 BlockSignals(True, SIGTERM);
526 if (FD_ISSET(ClientNMB,&fds))
528 struct packet_struct *packet = read_packet(ClientNMB, NMB_PACKET);
531 if (ismyip(packet->ip) && packet->port == NMB_PORT)
533 DEBUG(7,("discarding own packet from %s:%d\n",
534 inet_ntoa(packet->ip),packet->port));
539 queue_packet(packet);
544 if (FD_ISSET(ClientDGRAM,&fds))
546 struct packet_struct *packet = read_packet(ClientDGRAM, DGRAM_PACKET);
549 if (ismyip(packet->ip) && packet->port == DGRAM_PORT)
551 DEBUG(7,("discarding own packet from %s:%d\n",
552 inet_ntoa(packet->ip),packet->port));
557 queue_packet(packet);
565 /****************************************************************************
566 construct and send a netbios DGRAM
568 Note that this currently sends all answers to port 138. thats the
569 wrong things to do! I should send to the requestors port. XXX
570 **************************************************************************/
571 BOOL send_mailslot_reply(BOOL unique, char *mailslot,int fd,char *buf,int len,char *srcname,
572 char *dstname,int src_type,int dest_type,
573 struct in_addr dest_ip,struct in_addr src_ip)
575 struct packet_struct p;
576 struct dgram_packet *dgram = &p.packet.dgram;
580 /* ha ha. no. do NOT send packets to 255.255.255.255: it's a pseudo address */
581 if (ip_equal(wins_ip, dest_ip)) return False;
583 bzero((char *)&p,sizeof(p));
585 update_name_trn_id();
587 /* DIRECT GROUP or UNIQUE datagram */
588 dgram->header.msg_type = unique ? 0x10 : 0x11;
589 dgram->header.flags.node_type = M_NODE;
590 dgram->header.flags.first = True;
591 dgram->header.flags.more = False;
592 dgram->header.dgm_id = name_trn_id;
593 dgram->header.source_ip = src_ip;
594 dgram->header.source_port = DGRAM_PORT;
595 dgram->header.dgm_length = 0; /* let build_dgram() handle this */
596 dgram->header.packet_offset = 0;
598 make_nmb_name(&dgram->source_name,srcname,src_type,scope);
599 make_nmb_name(&dgram->dest_name,dstname,dest_type,scope);
601 ptr = &dgram->data[0];
603 /* now setup the smb part */
604 ptr -= 4; /* XXX ugliness because of handling of tcp SMB length */
606 set_message(ptr,17,17 + len,True);
609 CVAL(ptr,smb_com) = SMBtrans;
610 SSVAL(ptr,smb_vwv1,len);
611 SSVAL(ptr,smb_vwv11,len);
612 SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
613 SSVAL(ptr,smb_vwv13,3);
614 SSVAL(ptr,smb_vwv14,1);
615 SSVAL(ptr,smb_vwv15,1);
616 SSVAL(ptr,smb_vwv16,2);
619 p2 = skip_string(p2,1);
624 dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length */
629 p.timestamp = time(NULL);
630 p.packet_type = DGRAM_PACKET;
632 DEBUG(4,("send mailslot %s from %s %s", mailslot,
633 inet_ntoa(src_ip),namestr(&dgram->source_name)));
634 DEBUG(4,("to %s %s\n", inet_ntoa(dest_ip),namestr(&dgram->dest_name)));
636 return(send_packet(&p));