This commit was manufactured by cvs2svn to create tag
[Samba.git] / source / namepacket.c
blobe6677ee10dae9b2f0a22bafa0f9f504b6f15af88
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
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 ipgrp;
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;
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 = nmb->question.question_type;
156 nmb->additional->rr_class = nmb->question.question_class;
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;
162 nmb->additional->rdlength = 6;
163 nmb->additional->rdata[0] = nb_flags;
164 putip(&nmb->additional->rdata[2],(char *)iface_ip(to_ip));
167 p.ip = to_ip;
168 p.port = NMB_PORT;
169 p.fd = fd;
170 p.timestamp = time(NULL);
171 p.packet_type = NMB_PACKET;
173 if (!send_packet(&p)) {
174 DEBUG(3,("send_packet to %s %d failed\n",inet_ntoa(p.ip),p.port));
175 *id = 0xffff;
178 return;
182 /****************************************************************************
183 reply to a netbios name packet
184 ****************************************************************************/
185 void reply_netbios_packet(struct packet_struct *p1,int trn_id,
186 int rcode, int rcv_code, int opcode, BOOL recurse,
187 struct nmb_name *rr_name,int rr_type,int rr_class,int ttl,
188 char *data,int len)
190 struct packet_struct p;
191 struct nmb_packet *nmb = &p.packet.nmb;
192 struct res_rec answers;
193 char *packet_type = "unknown";
194 BOOL recursion_desired = False;
196 p = *p1;
198 switch (rcv_code)
200 case NMB_STATUS:
202 packet_type = "nmb_status";
203 recursion_desired = True;
204 break;
206 case NMB_QUERY:
208 packet_type = "nmb_query";
209 recursion_desired = True;
210 break;
212 case NMB_REG:
214 packet_type = "nmb_reg";
215 recursion_desired = True;
216 break;
218 case NMB_REL:
220 packet_type = "nmb_rel";
221 recursion_desired = False;
222 break;
224 case NMB_WAIT_ACK:
226 packet_type = "nmb_wack";
227 recursion_desired = False;
228 break;
230 default:
232 DEBUG(1,("replying netbios packet: %s %s\n",
233 packet_type, namestr(rr_name), inet_ntoa(p.ip)));
235 return;
239 DEBUG(4,("replying netbios packet: %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 = recurse;
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 d = find_subnet(p->ip);
325 n1 = find_name_search(&d,n,FIND_LOCAL|FIND_WINS|FIND_SELF,p->ip);
327 return (n1 != NULL);
331 /****************************************************************************
332 process udp 138 datagrams
333 ****************************************************************************/
334 static void process_dgram(struct packet_struct *p)
336 char *buf;
337 char *buf2;
338 int len;
339 struct dgram_packet *dgram = &p->packet.dgram;
341 /* if we aren't listening to the destination name then ignore the packet */
342 if (!listening(p,&dgram->dest_name))
343 return;
346 if (dgram->header.msg_type != 0x10 &&
347 dgram->header.msg_type != 0x11 &&
348 dgram->header.msg_type != 0x12) {
349 /* don't process error packets etc yet */
350 return;
353 buf = &dgram->data[0];
354 buf -= 4; /* XXXX for the pseudo tcp length -
355 someday I need to get rid of this */
357 if (CVAL(buf,smb_com) != SMBtrans) return;
359 len = SVAL(buf,smb_vwv11);
360 buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
362 DEBUG(4,("datagram from %s to %s for %s of type %d len=%d\n",
363 namestr(&dgram->source_name),namestr(&dgram->dest_name),
364 smb_buf(buf),CVAL(buf2,0),len));
367 if (len <= 0) return;
369 /* datagram packet received for the browser mailslot */
370 if (strequal(smb_buf(buf),BROWSE_MAILSLOT)) {
371 process_browse_packet(p,buf2,len);
372 return;
375 /* datagram packet received for the domain log on mailslot */
376 if (strequal(smb_buf(buf),NET_LOGON_MAILSLOT)) {
377 process_logon_packet(p,buf2,len);
378 return;
382 /****************************************************************************
383 process a nmb packet
384 ****************************************************************************/
385 static void process_nmb(struct packet_struct *p)
387 struct nmb_packet *nmb = &p->packet.nmb;
389 debug_nmb_packet(p);
391 switch (nmb->header.opcode)
393 case 8: /* what is this?? */
394 case NMB_REG:
395 case NMB_REG_REFRESH:
397 if (nmb->header.response)
399 if (nmb->header.ancount ==0) break;
400 response_netbios_packet(p); /* response to registration dealt
401 with here */
403 else
405 if (nmb->header.qdcount==0 || nmb->header.arcount==0) break;
406 reply_name_reg(p);
408 break;
411 case 0:
413 if (nmb->header.response)
415 switch (nmb->question.question_type)
417 case 0x0:
419 response_netbios_packet(p);
420 break;
423 return;
425 else if (nmb->header.qdcount>0)
427 switch (nmb->question.question_type)
429 case NMB_QUERY:
431 reply_name_query(p);
432 break;
434 case NMB_STATUS:
436 reply_name_status(p);
437 break;
440 return;
442 break;
445 case NMB_REL:
447 if (nmb->header.response)
449 if (nmb->header.ancount ==0) break;
450 response_netbios_packet(p); /* response to release dealt
451 with here */
453 else
455 if (nmb->header.qdcount==0 || nmb->header.arcount==0) break;
456 reply_name_release(p);
458 break;
464 /*******************************************************************
465 run elements off the packet queue till its empty
466 ******************************************************************/
467 void run_packet_queue()
469 struct packet_struct *p;
471 while ((p=packet_queue))
473 switch (p->packet_type)
475 case NMB_PACKET:
476 process_nmb(p);
477 break;
479 case DGRAM_PACKET:
480 process_dgram(p);
481 break;
484 packet_queue = packet_queue->next;
485 if (packet_queue) packet_queue->prev = NULL;
486 free_packet(p);
490 /****************************************************************************
491 listens for NMB or DGRAM packets, and queues them
492 ***************************************************************************/
493 void listen_for_packets(BOOL run_election)
495 fd_set fds;
496 int selrtn;
497 struct timeval timeout;
499 try_again:
501 FD_ZERO(&fds);
502 FD_SET(ClientNMB,&fds);
503 FD_SET(ClientDGRAM,&fds);
505 /* during elections and when expecting a netbios response packet we
506 need to send election packets at tighter intervals
508 ideally it needs to be the interval (in ms) between time now and
509 the time we are expecting the next netbios packet */
511 timeout.tv_sec = (run_election||num_response_packets) ? 1 : NMBD_SELECT_LOOP;
512 timeout.tv_usec = 0;
514 selrtn = sys_select(&fds,&timeout);
516 if (FD_ISSET(ClientNMB,&fds))
518 struct packet_struct *packet = read_packet(ClientNMB, NMB_PACKET);
519 if (packet) {
520 if (ismyip(packet->ip) &&
521 (packet->port == NMB_PORT || packet->port == DGRAM_PORT)) {
522 DEBUG(7,("discarding own packet from %s:%d\n",
523 inet_ntoa(packet->ip),packet->port));
524 free_packet(packet);
525 goto try_again;
526 } else {
527 queue_packet(packet);
532 if (FD_ISSET(ClientDGRAM,&fds))
534 struct packet_struct *packet = read_packet(ClientDGRAM, DGRAM_PACKET);
535 if (packet) {
536 if (ismyip(packet->ip) &&
537 (packet->port == NMB_PORT || packet->port == DGRAM_PORT)) {
538 DEBUG(7,("discarding own packet from %s:%d\n",
539 inet_ntoa(packet->ip),packet->port));
540 free_packet(packet);
541 goto try_again;
542 } else {
543 queue_packet(packet);
551 /****************************************************************************
552 construct and send a netbios DGRAM
554 Note that this currently sends all answers to port 138. thats the
555 wrong things to do! I should send to the requestors port. XXX
556 **************************************************************************/
557 BOOL send_mailslot_reply(char *mailslot,int fd,char *buf,int len,char *srcname,
558 char *dstname,int src_type,int dest_type,
559 struct in_addr dest_ip,struct in_addr src_ip)
561 struct packet_struct p;
562 struct dgram_packet *dgram = &p.packet.dgram;
563 struct in_addr wins_ip = ipgrp;
564 char *ptr,*p2;
565 char tmp[4];
567 /* ha ha. no. do NOT send packets to 255.255.255.255: it's a pseudo address */
568 if (ip_equal(wins_ip, dest_ip)) return False;
570 bzero((char *)&p,sizeof(p));
572 update_name_trn_id();
574 dgram->header.msg_type = 0x11; /* DIRECT GROUP DATAGRAM */
575 dgram->header.flags.node_type = M_NODE;
576 dgram->header.flags.first = True;
577 dgram->header.flags.more = False;
578 dgram->header.dgm_id = name_trn_id;
579 dgram->header.source_ip = src_ip;
580 dgram->header.source_port = DGRAM_PORT;
581 dgram->header.dgm_length = 0; /* let build_dgram() handle this */
582 dgram->header.packet_offset = 0;
584 make_nmb_name(&dgram->source_name,srcname,src_type,scope);
585 make_nmb_name(&dgram->dest_name,dstname,dest_type,scope);
587 ptr = &dgram->data[0];
589 /* now setup the smb part */
590 ptr -= 4; /* XXX ugliness because of handling of tcp SMB length */
591 memcpy(tmp,ptr,4);
592 set_message(ptr,17,17 + len,True);
593 memcpy(ptr,tmp,4);
595 CVAL(ptr,smb_com) = SMBtrans;
596 SSVAL(ptr,smb_vwv1,len);
597 SSVAL(ptr,smb_vwv11,len);
598 SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
599 SSVAL(ptr,smb_vwv13,3);
600 SSVAL(ptr,smb_vwv14,1);
601 SSVAL(ptr,smb_vwv15,1);
602 SSVAL(ptr,smb_vwv16,2);
603 p2 = smb_buf(ptr);
604 strcpy(p2,mailslot);
605 p2 = skip_string(p2,1);
607 memcpy(p2,buf,len);
608 p2 += len;
610 dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length */
612 p.ip = dest_ip;
613 p.port = DGRAM_PORT;
614 p.fd = ClientDGRAM;
615 p.timestamp = time(NULL);
616 p.packet_type = DGRAM_PACKET;
618 DEBUG(4,("send mailslot %s from %s %s", mailslot,
619 inet_ntoa(src_ip),namestr(&dgram->source_name)));
620 DEBUG(4,("to %s %s\n", inet_ntoa(dest_ip),namestr(&dgram->dest_name)));
622 return(send_packet(&p));