compile errors. oops.
[Samba/gbeck.git] / source / namepacket.c
blob043e2c02f0fdd3b5c5766fc2284ca47771434b47
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 == 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();
160 else
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));
168 p.ip = to_ip;
169 p.port = NMB_PORT;
170 p.fd = fd;
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));
178 *id = 0xffff;
181 return;
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,
191 char *data,int len)
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;
199 p = *p1;
201 switch (rcv_code)
203 case NMB_STATUS:
205 packet_type = "nmb_status";
206 recursion_desired = True;
207 break;
209 case NMB_QUERY:
211 packet_type = "nmb_query";
212 recursion_desired = True;
213 break;
215 case NMB_REG:
217 packet_type = "nmb_reg";
218 recursion_desired = True;
219 break;
221 case NMB_REL:
223 packet_type = "nmb_rel";
224 recursion_desired = False;
225 break;
227 case NMB_WAIT_ACK:
229 packet_type = "nmb_wack";
230 recursion_desired = False;
231 break;
233 default:
235 DEBUG(1,("replying netbios packet: %s %s\n",
236 packet_type, namestr(rr_name), inet_ntoa(p.ip)));
238 return;
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;
270 if (data && len)
272 nmb->answers->rdlength = len;
273 memcpy(nmb->answers->rdata, data, len);
276 p.packet_type = NMB_PACKET;
278 debug_nmb_packet(&p);
280 send_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;
298 if (!packet_queue) {
299 packet->prev = NULL;
300 packet->next = NULL;
301 packet_queue = packet;
302 return;
305 /* find the bottom */
306 for (p=packet_queue;p->next;p=p->next) ;
308 p->next = packet;
309 packet->next = NULL;
310 packet->prev = p;
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 d = find_subnet(p->ip);
328 n1 = find_name_search(&d,n,FIND_LOCAL|FIND_WINS|FIND_SELF,p->ip);
330 return (n1 != NULL);
334 /****************************************************************************
335 process udp 138 datagrams
336 ****************************************************************************/
337 static void process_dgram(struct packet_struct *p)
339 char *buf;
340 char *buf2;
341 int len;
342 struct dgram_packet *dgram = &p->packet.dgram;
344 /* if we aren't listening to the destination name then ignore the packet */
345 if (!listening(p,&dgram->dest_name))
346 return;
349 if (dgram->header.msg_type != 0x10 &&
350 dgram->header.msg_type != 0x11 &&
351 dgram->header.msg_type != 0x12) {
352 /* don't process error packets etc yet */
353 return;
356 buf = &dgram->data[0];
357 buf -= 4; /* XXXX for the pseudo tcp length -
358 someday I need to get rid of this */
360 if (CVAL(buf,smb_com) != SMBtrans) return;
362 len = SVAL(buf,smb_vwv11);
363 buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
365 DEBUG(4,("datagram from %s to %s for %s of type %d len=%d\n",
366 namestr(&dgram->source_name),namestr(&dgram->dest_name),
367 smb_buf(buf),CVAL(buf2,0),len));
370 if (len <= 0) return;
372 /* datagram packet received for the browser mailslot */
373 if (strequal(smb_buf(buf),BROWSE_MAILSLOT)) {
374 process_browse_packet(p,buf2,len);
375 return;
378 /* datagram packet received for the domain log on mailslot */
379 if (strequal(smb_buf(buf),NET_LOGON_MAILSLOT)) {
380 process_logon_packet(p,buf2,len);
381 return;
385 /****************************************************************************
386 process a nmb packet
387 ****************************************************************************/
388 static void process_nmb(struct packet_struct *p)
390 struct nmb_packet *nmb = &p->packet.nmb;
392 debug_nmb_packet(p);
394 switch (nmb->header.opcode)
396 case 8: /* what is this?? */
397 case NMB_REG:
398 case NMB_REG_REFRESH:
400 if (nmb->header.response)
402 if (nmb->header.ancount ==0) break;
403 response_netbios_packet(p); /* response to registration dealt
404 with here */
406 else
408 if (nmb->header.qdcount==0 || nmb->header.arcount==0) break;
409 reply_name_reg(p);
411 break;
414 case 0:
416 if (nmb->header.response)
418 switch (nmb->question.question_type)
420 case 0x0:
422 response_netbios_packet(p);
423 break;
426 return;
428 else if (nmb->header.qdcount>0)
430 switch (nmb->question.question_type)
432 case NMB_QUERY:
434 reply_name_query(p);
435 break;
437 case NMB_STATUS:
439 reply_name_status(p);
440 break;
443 return;
445 break;
448 case NMB_REL:
450 if (nmb->header.response)
452 if (nmb->header.ancount ==0) break;
453 response_netbios_packet(p); /* response to release dealt
454 with here */
456 else
458 if (nmb->header.qdcount==0 || nmb->header.arcount==0) break;
459 reply_name_release(p);
461 break;
467 /*******************************************************************
468 run elements off the packet queue till its empty
469 ******************************************************************/
470 void run_packet_queue()
472 struct packet_struct *p;
474 while ((p=packet_queue))
476 switch (p->packet_type)
478 case NMB_PACKET:
479 process_nmb(p);
480 break;
482 case DGRAM_PACKET:
483 process_dgram(p);
484 break;
487 packet_queue = packet_queue->next;
488 if (packet_queue) packet_queue->prev = NULL;
489 free_packet(p);
493 /****************************************************************************
494 listens for NMB or DGRAM packets, and queues them
495 ***************************************************************************/
496 void listen_for_packets(BOOL run_election)
498 fd_set fds;
499 int selrtn;
500 struct timeval timeout;
502 FD_ZERO(&fds);
503 FD_SET(ClientNMB,&fds);
504 FD_SET(ClientDGRAM,&fds);
506 /* during elections and when expecting a netbios response packet we
507 need to send election packets at tighter intervals
509 ideally it needs to be the interval (in ms) between time now and
510 the time we are expecting the next netbios packet */
512 timeout.tv_sec = (run_election||num_response_packets) ? 1:NMBD_SELECT_LOOP;
513 timeout.tv_usec = 0;
515 selrtn = sys_select(&fds,&timeout);
517 if (FD_ISSET(ClientNMB,&fds))
519 struct packet_struct *packet = read_packet(ClientNMB, NMB_PACKET);
520 if (packet)
522 if (ismyip(packet->ip) && packet->port == NMB_PORT)
524 DEBUG(7,("discarding own packet from %s:%d\n",
525 inet_ntoa(packet->ip),packet->port));
526 free_packet(packet);
528 else
530 queue_packet(packet);
535 if (FD_ISSET(ClientDGRAM,&fds))
537 struct packet_struct *packet = read_packet(ClientDGRAM, DGRAM_PACKET);
538 if (packet)
540 if (ismyip(packet->ip) && packet->port == DGRAM_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);
556 /****************************************************************************
557 construct and send a netbios DGRAM
559 Note that this currently sends all answers to port 138. thats the
560 wrong things to do! I should send to the requestors port. XXX
561 **************************************************************************/
562 BOOL send_mailslot_reply(BOOL unique, char *mailslot,int fd,char *buf,int len,char *srcname,
563 char *dstname,int src_type,int dest_type,
564 struct in_addr dest_ip,struct in_addr src_ip)
566 struct packet_struct p;
567 struct dgram_packet *dgram = &p.packet.dgram;
568 struct in_addr wins_ip = ipgrp;
569 char *ptr,*p2;
570 char tmp[4];
572 /* ha ha. no. do NOT send packets to 255.255.255.255: it's a pseudo address */
573 if (ip_equal(wins_ip, dest_ip)) return False;
575 bzero((char *)&p,sizeof(p));
577 update_name_trn_id();
579 /* DIRECT GROUP or UNIQUE datagram */
580 dgram->header.msg_type = unique ? 0x10 : 0x11;
581 dgram->header.flags.node_type = M_NODE;
582 dgram->header.flags.first = True;
583 dgram->header.flags.more = False;
584 dgram->header.dgm_id = name_trn_id;
585 dgram->header.source_ip = src_ip;
586 dgram->header.source_port = DGRAM_PORT;
587 dgram->header.dgm_length = 0; /* let build_dgram() handle this */
588 dgram->header.packet_offset = 0;
590 make_nmb_name(&dgram->source_name,srcname,src_type,scope);
591 make_nmb_name(&dgram->dest_name,dstname,dest_type,scope);
593 ptr = &dgram->data[0];
595 /* now setup the smb part */
596 ptr -= 4; /* XXX ugliness because of handling of tcp SMB length */
597 memcpy(tmp,ptr,4);
598 set_message(ptr,17,17 + len,True);
599 memcpy(ptr,tmp,4);
601 CVAL(ptr,smb_com) = SMBtrans;
602 SSVAL(ptr,smb_vwv1,len);
603 SSVAL(ptr,smb_vwv11,len);
604 SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
605 SSVAL(ptr,smb_vwv13,3);
606 SSVAL(ptr,smb_vwv14,1);
607 SSVAL(ptr,smb_vwv15,1);
608 SSVAL(ptr,smb_vwv16,2);
609 p2 = smb_buf(ptr);
610 strcpy(p2,mailslot);
611 p2 = skip_string(p2,1);
613 memcpy(p2,buf,len);
614 p2 += len;
616 dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length */
618 p.ip = dest_ip;
619 p.port = DGRAM_PORT;
620 p.fd = ClientDGRAM;
621 p.timestamp = time(NULL);
622 p.packet_type = DGRAM_PACKET;
624 DEBUG(4,("send mailslot %s from %s %s", mailslot,
625 inet_ntoa(src_ip),namestr(&dgram->source_name)));
626 DEBUG(4,("to %s %s\n", inet_ntoa(dest_ip),namestr(&dgram->dest_name)));
628 return(send_packet(&p));