sorted out various timer delay bugs: nameannounce.c nameserv.c
[Samba.git] / source / namepacket.c
blob5afdb8af0eda8545a8feaee4d4f1bb324c0c46eb
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;
43 /***************************************************************************
44 updates the unique transaction identifier
45 **************************************************************************/
46 static void update_name_trn_id(void)
48 if (!name_trn_id)
50 name_trn_id = (time(NULL)%(unsigned)0x7FFF) + (getpid()%(unsigned)100);
52 name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
56 /****************************************************************************
57 initiate a netbios packet
58 ****************************************************************************/
59 void initiate_netbios_packet(uint16 *id,
60 int fd,int quest_type,char *name,int name_type,
61 int nb_flags,BOOL bcast,BOOL recurse,
62 struct in_addr to_ip)
64 struct packet_struct p;
65 struct nmb_packet *nmb = &p.packet.nmb;
66 struct res_rec additional_rec;
67 char *packet_type = "unknown";
68 int opcode = -1;
70 if (!id) return;
72 if (quest_type == NMB_STATUS) { packet_type = "nmb_status"; opcode = 0; }
73 if (quest_type == NMB_QUERY ) { packet_type = "nmb_query"; opcode = 0; }
74 if (quest_type == NMB_REG ) { packet_type = "nmb_reg"; opcode = 5; }
75 if (quest_type == NMB_REL ) { packet_type = "nmb_rel"; opcode = 6; }
77 DEBUG(4,("initiating netbios packet: %s %s(%x) (bcast=%s) %s\n",
78 packet_type, name, name_type, BOOLSTR(bcast), inet_ntoa(to_ip)));
80 if (opcode == -1) return;
82 bzero((char *)&p,sizeof(p));
84 if (*id == 0xffff) {
85 update_name_trn_id();
86 *id = name_trn_id; /* allow resending with same id */
89 nmb->header.name_trn_id = *id;
90 nmb->header.opcode = opcode;
91 nmb->header.response = False;
93 nmb->header.nm_flags.bcast = bcast;
94 nmb->header.nm_flags.recursion_available = CanRecurse;
95 nmb->header.nm_flags.recursion_desired = recurse;
96 nmb->header.nm_flags.trunc = False;
97 nmb->header.nm_flags.authoritative = False;
99 nmb->header.rcode = 0;
100 nmb->header.qdcount = 1;
101 nmb->header.ancount = 0;
102 nmb->header.nscount = 0;
103 nmb->header.arcount = (quest_type==NMB_REG || quest_type==NMB_REL) ? 1 : 0;
105 make_nmb_name(&nmb->question.question_name,name,name_type,scope);
107 nmb->question.question_type = quest_type;
108 nmb->question.question_class = 0x1;
110 if (quest_type == NMB_REG || quest_type == NMB_REL)
112 nmb->additional = &additional_rec;
113 bzero((char *)nmb->additional,sizeof(*nmb->additional));
115 nmb->additional->rr_name = nmb->question.question_name;
116 nmb->additional->rr_type = nmb->question.question_type;
117 nmb->additional->rr_class = nmb->question.question_class;
119 nmb->additional->ttl = quest_type == NMB_REG ? lp_max_ttl() : 0;
120 nmb->additional->rdlength = 6;
121 nmb->additional->rdata[0] = nb_flags;
122 putip(&nmb->additional->rdata[2],(char *)iface_ip(to_ip));
125 p.ip = to_ip;
126 p.port = NMB_PORT;
127 p.fd = fd;
128 p.timestamp = time(NULL);
129 p.packet_type = NMB_PACKET;
131 if (!send_packet(&p)) *id = 0xffff;
133 return;
137 /****************************************************************************
138 reply to a netbios name packet
139 ****************************************************************************/
140 void reply_netbios_packet(struct packet_struct *p1,int trn_id,
141 int rcode,int opcode, BOOL recurse,
142 struct nmb_name *rr_name,int rr_type,int rr_class,int ttl,
143 char *data,int len)
145 struct packet_struct p;
146 struct nmb_packet *nmb = &p.packet.nmb;
147 struct res_rec answers;
148 char *packet_type = "unknown";
149 BOOL recursion_desired = False;
151 p = *p1;
153 switch (rr_type)
155 case NMB_STATUS:
157 packet_type = "nmb_status";
158 recursion_desired = True;
159 break;
161 case NMB_QUERY:
163 packet_type = "nmb_query";
164 recursion_desired = True;
165 break;
167 case NMB_REG:
169 packet_type = "nmb_reg";
170 recursion_desired = True;
171 break;
173 case NMB_REL:
175 packet_type = "nmb_rel";
176 recursion_desired = False;
177 break;
179 case NMB_WAIT_ACK:
181 packet_type = "nmb_wack";
182 recursion_desired = False;
183 break;
185 default:
187 DEBUG(1,("replying netbios packet: %s %s\n",
188 packet_type, namestr(rr_name), inet_ntoa(p.ip)));
190 return;
194 DEBUG(4,("replying netbios packet: %s %s\n",
195 packet_type, namestr(rr_name), inet_ntoa(p.ip)));
197 nmb->header.name_trn_id = trn_id;
198 nmb->header.opcode = opcode;
199 nmb->header.response = True;
200 nmb->header.nm_flags.bcast = False;
201 nmb->header.nm_flags.recursion_available = recurse;
202 nmb->header.nm_flags.recursion_desired = recursion_desired;
203 nmb->header.nm_flags.trunc = False;
204 nmb->header.nm_flags.authoritative = True;
206 nmb->header.qdcount = 0;
207 nmb->header.ancount = 1;
208 nmb->header.nscount = 0;
209 nmb->header.arcount = 0;
210 nmb->header.rcode = 0;
212 bzero((char*)&nmb->question,sizeof(nmb->question));
214 nmb->answers = &answers;
215 bzero((char*)nmb->answers,sizeof(*nmb->answers));
217 nmb->answers->rr_name = *rr_name;
218 nmb->answers->rr_type = rr_type;
219 nmb->answers->rr_class = rr_class;
220 nmb->answers->ttl = ttl;
222 if (data && len)
224 nmb->answers->rdlength = len;
225 memcpy(nmb->answers->rdata, data, len);
228 p.packet_type = NMB_PACKET;
230 debug_nmb_packet(&p);
232 send_packet(&p);
236 /*******************************************************************
237 the global packet linked-list. incoming entries are added to the
238 end of this list. it is supposed to remain fairly short so we
239 won't bother with an end pointer.
240 ******************************************************************/
241 static struct packet_struct *packet_queue = NULL;
243 /*******************************************************************
244 queue a packet into the packet queue
245 ******************************************************************/
246 void queue_packet(struct packet_struct *packet)
248 struct packet_struct *p;
250 if (!packet_queue) {
251 packet->prev = NULL;
252 packet->next = NULL;
253 packet_queue = packet;
254 return;
257 /* find the bottom */
258 for (p=packet_queue;p->next;p=p->next) ;
260 p->next = packet;
261 packet->next = NULL;
262 packet->prev = p;
266 /****************************************************************************
267 process udp 138 datagrams
268 ****************************************************************************/
269 static void process_dgram(struct packet_struct *p)
271 char *buf;
272 char *buf2;
273 int len;
274 struct dgram_packet *dgram = &p->packet.dgram;
276 if (dgram->header.msg_type != 0x10 &&
277 dgram->header.msg_type != 0x11 &&
278 dgram->header.msg_type != 0x12) {
279 /* don't process error packets etc yet */
280 return;
283 buf = &dgram->data[0];
284 buf -= 4; /* XXXX for the pseudo tcp length -
285 someday I need to get rid of this */
287 if (CVAL(buf,smb_com) != SMBtrans) return;
289 len = SVAL(buf,smb_vwv11);
290 buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
292 DEBUG(4,("datagram from %s to %s for %s of type %d len=%d\n",
293 namestr(&dgram->source_name),namestr(&dgram->dest_name),
294 smb_buf(buf),CVAL(buf2,0),len));
297 if (len <= 0) return;
299 /* datagram packet received for the browser mailslot */
300 if (strequal(smb_buf(buf),BROWSE_MAILSLOT)) {
301 process_browse_packet(p,buf2,len);
302 return;
305 /* datagram packet received for the domain log on mailslot */
306 if (strequal(smb_buf(buf),NET_LOGON_MAILSLOT)) {
307 process_logon_packet(p,buf2,len);
308 return;
312 /****************************************************************************
313 process a nmb packet
314 ****************************************************************************/
315 static void process_nmb(struct packet_struct *p)
317 struct nmb_packet *nmb = &p->packet.nmb;
319 debug_nmb_packet(p);
321 switch (nmb->header.opcode)
323 case 8: /* what is this?? */
324 case NMB_REG:
325 case NMB_REG_REFRESH:
327 if (nmb->header.qdcount==0 || nmb->header.arcount==0) break;
328 if (nmb->header.response)
329 response_netbios_packet(p); /* response to registration dealt with here */
330 else
331 reply_name_reg(p);
332 break;
335 case 0:
337 if (nmb->header.response)
339 switch (nmb->question.question_type)
341 case 0x0:
343 response_netbios_packet(p);
344 break;
347 return;
349 else if (nmb->header.qdcount>0)
351 switch (nmb->question.question_type)
353 case NMB_QUERY:
355 reply_name_query(p);
356 break;
358 case NMB_STATUS:
360 reply_name_status(p);
361 break;
364 return;
366 break;
369 case NMB_REL:
371 if (nmb->header.qdcount==0 || nmb->header.arcount==0)
373 DEBUG(2,("netbios release packet rejected\n"));
374 break;
377 if (nmb->header.response)
378 response_netbios_packet(p); /* response to reply dealt with in here */
379 else
380 reply_name_release(p);
381 break;
387 /*******************************************************************
388 run elements off the packet queue till its empty
389 ******************************************************************/
390 void run_packet_queue()
392 struct packet_struct *p;
394 while ((p=packet_queue))
396 switch (p->packet_type)
398 case NMB_PACKET:
399 process_nmb(p);
400 break;
402 case DGRAM_PACKET:
403 process_dgram(p);
404 break;
407 packet_queue = packet_queue->next;
408 if (packet_queue) packet_queue->prev = NULL;
409 free_packet(p);
413 /****************************************************************************
414 listens for NMB or DGRAM packets, and queues them
415 ***************************************************************************/
416 void listen_for_packets(BOOL run_election)
418 fd_set fds;
419 int selrtn;
420 struct timeval timeout;
422 FD_ZERO(&fds);
423 FD_SET(ClientNMB,&fds);
424 FD_SET(ClientDGRAM,&fds);
426 /* during elections and when expecting a netbios response packet we need
427 to send election packets at one second intervals.
428 XXXX actually, it needs to be the interval (in ms) between time now and the
429 time we are expecting the next netbios packet */
431 timeout.tv_sec = (run_election||num_response_packets) ? 1 : NMBD_SELECT_LOOP;
432 timeout.tv_usec = 0;
434 selrtn = sys_select(&fds,&timeout);
436 if (FD_ISSET(ClientNMB,&fds))
438 struct packet_struct *packet = read_packet(ClientNMB, NMB_PACKET);
439 if (packet) {
440 #if 1
441 if (ismyip(packet->ip) &&
442 (packet->port == NMB_PORT || packet->port == DGRAM_PORT)) {
443 DEBUG(5,("discarding own packet from %s:%d\n",
444 inet_ntoa(packet->ip),packet->port));
445 free_packet(packet);
446 } else
447 #endif
449 queue_packet(packet);
454 if (FD_ISSET(ClientDGRAM,&fds))
456 struct packet_struct *packet = read_packet(ClientDGRAM, DGRAM_PACKET);
457 if (packet) {
458 #if 1
459 if (ismyip(packet->ip) &&
460 (packet->port == NMB_PORT || packet->port == DGRAM_PORT)) {
461 DEBUG(5,("discarding own packet from %s:%d\n",
462 inet_ntoa(packet->ip),packet->port));
463 free_packet(packet);
464 } else
465 #endif
467 queue_packet(packet);
475 /****************************************************************************
476 construct and send a netbios DGRAM
478 Note that this currently sends all answers to port 138. thats the
479 wrong things to do! I should send to the requestors port. XXX
480 **************************************************************************/
481 BOOL send_mailslot_reply(char *mailslot,int fd,char *buf,int len,char *srcname,
482 char *dstname,int src_type,int dest_type,
483 struct in_addr dest_ip,struct in_addr src_ip)
485 struct packet_struct p;
486 struct dgram_packet *dgram = &p.packet.dgram;
487 struct in_addr wins_ip = ipgrp;
488 char *ptr,*p2;
489 char tmp[4];
491 /* ha ha. no. do NOT send packets to 255.255.255.255: it's a pseudo address */
492 if (ip_equal(wins_ip, dest_ip)) return False;
494 bzero((char *)&p,sizeof(p));
496 update_name_trn_id();
498 dgram->header.msg_type = 0x11; /* DIRECT GROUP DATAGRAM */
499 dgram->header.flags.node_type = M_NODE;
500 dgram->header.flags.first = True;
501 dgram->header.flags.more = False;
502 dgram->header.dgm_id = name_trn_id;
503 dgram->header.source_ip = src_ip;
504 dgram->header.source_port = DGRAM_PORT;
505 dgram->header.dgm_length = 0; /* let build_dgram() handle this */
506 dgram->header.packet_offset = 0;
508 make_nmb_name(&dgram->source_name,srcname,src_type,scope);
509 make_nmb_name(&dgram->dest_name,dstname,dest_type,scope);
511 ptr = &dgram->data[0];
513 /* now setup the smb part */
514 ptr -= 4; /* XXX ugliness because of handling of tcp SMB length */
515 memcpy(tmp,ptr,4);
516 set_message(ptr,17,17 + len,True);
517 memcpy(ptr,tmp,4);
519 CVAL(ptr,smb_com) = SMBtrans;
520 SSVAL(ptr,smb_vwv1,len);
521 SSVAL(ptr,smb_vwv11,len);
522 SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
523 SSVAL(ptr,smb_vwv13,3);
524 SSVAL(ptr,smb_vwv14,1);
525 SSVAL(ptr,smb_vwv15,1);
526 SSVAL(ptr,smb_vwv16,2);
527 p2 = smb_buf(ptr);
528 strcpy(p2,mailslot);
529 p2 = skip_string(p2,1);
531 memcpy(p2,buf,len);
532 p2 += len;
534 dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length */
536 p.ip = dest_ip;
537 p.port = DGRAM_PORT;
538 p.fd = ClientDGRAM;
539 p.timestamp = time(NULL);
540 p.packet_type = DGRAM_PACKET;
542 return(send_packet(&p));