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", 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
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
,
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
;
205 packet_type
= "nmb_status";
206 recursion_desired
= True
;
211 packet_type
= "nmb_query";
212 recursion_desired
= True
;
217 packet_type
= "nmb_reg";
218 recursion_desired
= True
;
223 packet_type
= "nmb_rel";
224 recursion_desired
= False
;
229 packet_type
= "nmb_wack";
230 recursion_desired
= False
;
235 DEBUG(1,("replying netbios packet: %s %s\n",
236 packet_type
, namestr(rr_name
), inet_ntoa(p
.ip
)));
242 DEBUG(4,("replying netbios packet: %s %s\n",
243 packet_type
, namestr(rr_name
), inet_ntoa(p
.ip
)));
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
;
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
;
260 bzero((char*)&nmb
->question
,sizeof(nmb
->question
));
262 nmb
->answers
= &answers
;
263 bzero((char*)nmb
->answers
,sizeof(*nmb
->answers
));
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
;
272 nmb
->answers
->rdlength
= len
;
273 memcpy(nmb
->answers
->rdata
, data
, len
);
276 p
.packet_type
= NMB_PACKET
;
278 debug_nmb_packet(&p
);
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
;
291 /*******************************************************************
292 queue a packet into the packet queue
293 ******************************************************************/
294 void queue_packet(struct packet_struct
*packet
)
296 struct packet_struct
*p
;
301 packet_queue
= packet
;
305 /* find the bottom */
306 for (p
=packet_queue
;p
->next
;p
=p
->next
) ;
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.
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
)
323 struct subnet_record
*d
;
324 struct name_record
*n1
;
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
);
330 n1
= find_name_search(&d
,n
,FIND_LOCAL
|FIND_WINS
|FIND_SELF
,p
->ip
);
336 /****************************************************************************
337 process udp 138 datagrams
338 ****************************************************************************/
339 static void process_dgram(struct packet_struct
*p
)
344 struct dgram_packet
*dgram
= &p
->packet
.dgram
;
346 /* if we aren't listening to the destination name then ignore the packet */
347 if (!listening(p
,&dgram
->dest_name
))
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
)));
354 if (dgram
->header
.msg_type
!= 0x10 &&
355 dgram
->header
.msg_type
!= 0x11 &&
356 dgram
->header
.msg_type
!= 0x12)
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
));
366 buf
= &dgram
->data
[0];
367 buf
-= 4; /* XXXX for the pseudo tcp length -
368 someday I need to get rid of this */
370 if (CVAL(buf
,smb_com
) != SMBtrans
) return;
372 len
= SVAL(buf
,smb_vwv11
);
373 buf2
= smb_base(buf
) + SVAL(buf
,smb_vwv12
);
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
));
380 if (len
<= 0) return;
382 /* datagram packet received for the browser mailslot */
383 if (strequal(smb_buf(buf
),BROWSE_MAILSLOT
)) {
384 process_browse_packet(p
,buf2
,len
);
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
);
395 /****************************************************************************
397 ****************************************************************************/
398 static void process_nmb(struct packet_struct
*p
)
400 struct nmb_packet
*nmb
= &p
->packet
.nmb
;
404 switch (nmb
->header
.opcode
)
406 case 8: /* what is this?? */
408 case NMB_REG_REFRESH
:
410 if (nmb
->header
.response
)
412 if (nmb
->header
.ancount
==0) break;
413 response_netbios_packet(p
); /* response to registration dealt
418 if (nmb
->header
.qdcount
==0 || nmb
->header
.arcount
==0) break;
426 if (nmb
->header
.response
)
428 switch (nmb
->question
.question_type
)
432 response_netbios_packet(p
);
438 else if (nmb
->header
.qdcount
>0)
440 switch (nmb
->question
.question_type
)
449 reply_name_status(p
);
460 if (nmb
->header
.response
)
462 if (nmb
->header
.ancount
==0) break;
463 response_netbios_packet(p
); /* response to release dealt
468 if (nmb
->header
.qdcount
==0 || nmb
->header
.arcount
==0) break;
469 reply_name_release(p
);
477 /*******************************************************************
478 run elements off the packet queue till its empty
479 ******************************************************************/
480 void run_packet_queue()
482 struct packet_struct
*p
;
484 while ((p
=packet_queue
))
486 switch (p
->packet_type
)
497 packet_queue
= packet_queue
->next
;
498 if (packet_queue
) packet_queue
->prev
= NULL
;
503 /****************************************************************************
504 listens for NMB or DGRAM packets, and queues them
505 ***************************************************************************/
506 void listen_for_packets(BOOL run_election
)
510 struct timeval timeout
;
513 FD_SET(ClientNMB
,&fds
);
514 FD_SET(ClientDGRAM
,&fds
);
516 /* during elections and when expecting a netbios response packet we
517 need to send election packets at tighter intervals
519 ideally it needs to be the interval (in ms) between time now and
520 the time we are expecting the next netbios packet */
522 timeout
.tv_sec
= (run_election
||num_response_packets
) ? 1:NMBD_SELECT_LOOP
;
525 /* We can only take term signals when we are in the select. */
526 BlockSignals(False
, SIGTERM
);
527 selrtn
= sys_select(&fds
,&timeout
);
528 BlockSignals(True
, SIGTERM
);
530 if (FD_ISSET(ClientNMB
,&fds
))
532 struct packet_struct
*packet
= read_packet(ClientNMB
, NMB_PACKET
);
535 if (ismyip(packet
->ip
) && packet
->port
== NMB_PORT
)
537 DEBUG(7,("discarding own packet from %s:%d\n",
538 inet_ntoa(packet
->ip
),packet
->port
));
543 queue_packet(packet
);
548 if (FD_ISSET(ClientDGRAM
,&fds
))
550 struct packet_struct
*packet
= read_packet(ClientDGRAM
, DGRAM_PACKET
);
553 if (ismyip(packet
->ip
) && packet
->port
== DGRAM_PORT
)
555 DEBUG(7,("discarding own packet from %s:%d\n",
556 inet_ntoa(packet
->ip
),packet
->port
));
561 queue_packet(packet
);
569 /****************************************************************************
570 construct and send a netbios DGRAM
572 Note that this currently sends all answers to port 138. thats the
573 wrong things to do! I should send to the requestors port. XXX
574 **************************************************************************/
575 BOOL
send_mailslot_reply(BOOL unique
, char *mailslot
,int fd
,char *buf
,int len
,char *srcname
,
576 char *dstname
,int src_type
,int dest_type
,
577 struct in_addr dest_ip
,struct in_addr src_ip
)
579 struct packet_struct p
;
580 struct dgram_packet
*dgram
= &p
.packet
.dgram
;
584 /* ha ha. no. do NOT send packets to 255.255.255.255: it's a pseudo address */
585 if (ip_equal(wins_ip
, dest_ip
)) return False
;
587 bzero((char *)&p
,sizeof(p
));
589 update_name_trn_id();
591 /* DIRECT GROUP or UNIQUE datagram */
592 dgram
->header
.msg_type
= unique
? 0x10 : 0x11;
593 dgram
->header
.flags
.node_type
= M_NODE
;
594 dgram
->header
.flags
.first
= True
;
595 dgram
->header
.flags
.more
= False
;
596 dgram
->header
.dgm_id
= name_trn_id
;
597 dgram
->header
.source_ip
= src_ip
;
598 dgram
->header
.source_port
= DGRAM_PORT
;
599 dgram
->header
.dgm_length
= 0; /* let build_dgram() handle this */
600 dgram
->header
.packet_offset
= 0;
602 make_nmb_name(&dgram
->source_name
,srcname
,src_type
,scope
);
603 make_nmb_name(&dgram
->dest_name
,dstname
,dest_type
,scope
);
605 ptr
= &dgram
->data
[0];
607 /* now setup the smb part */
608 ptr
-= 4; /* XXX ugliness because of handling of tcp SMB length */
610 set_message(ptr
,17,17 + len
,True
);
613 CVAL(ptr
,smb_com
) = SMBtrans
;
614 SSVAL(ptr
,smb_vwv1
,len
);
615 SSVAL(ptr
,smb_vwv11
,len
);
616 SSVAL(ptr
,smb_vwv12
,70 + strlen(mailslot
));
617 SSVAL(ptr
,smb_vwv13
,3);
618 SSVAL(ptr
,smb_vwv14
,1);
619 SSVAL(ptr
,smb_vwv15
,1);
620 SSVAL(ptr
,smb_vwv16
,2);
623 p2
= skip_string(p2
,1);
628 dgram
->datasize
= PTR_DIFF(p2
,ptr
+4); /* +4 for tcp length */
633 p
.timestamp
= time(NULL
);
634 p
.packet_type
= DGRAM_PACKET
;
636 DEBUG(4,("send mailslot %s from %s %s", mailslot
,
637 inet_ntoa(src_ip
),namestr(&dgram
->source_name
)));
638 DEBUG(4,("to %s %s\n", inet_ntoa(dest_ip
),namestr(&dgram
->dest_name
)));
640 return(send_packet(&p
));