lots of changes to nmbd
[Samba.git] / source / namepacket.c
blobacedbc015115d3081163aa54b39ac218d88d8f5b
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_REL ) { packet_type = "nmb_rel"; opcode = 6; }
111 DEBUG(4,("initiating netbios packet: %s %s(%x) (bcast=%s) %s\n",
112 packet_type, name, name_type, BOOLSTR(bcast), inet_ntoa(to_ip)));
114 if (opcode == -1) return;
116 bzero((char *)&p,sizeof(p));
118 if (*id == 0xffff) {
119 update_name_trn_id();
120 *id = name_trn_id; /* allow resending with same id */
123 nmb->header.name_trn_id = *id;
124 nmb->header.opcode = opcode;
125 nmb->header.response = False;
127 nmb->header.nm_flags.bcast = bcast;
128 nmb->header.nm_flags.recursion_available = CanRecurse;
129 nmb->header.nm_flags.recursion_desired = recurse;
130 nmb->header.nm_flags.trunc = False;
131 nmb->header.nm_flags.authoritative = False;
133 nmb->header.rcode = 0;
134 nmb->header.qdcount = 1;
135 nmb->header.ancount = 0;
136 nmb->header.nscount = 0;
137 nmb->header.arcount = (quest_type==NMB_REG || quest_type==NMB_REL) ? 1 : 0;
139 make_nmb_name(&nmb->question.question_name,name,name_type,scope);
141 nmb->question.question_type = quest_type;
142 nmb->question.question_class = 0x1;
144 if (quest_type == NMB_REG || quest_type == NMB_REL)
146 nmb->additional = &additional_rec;
147 bzero((char *)nmb->additional,sizeof(*nmb->additional));
149 nmb->additional->rr_name = nmb->question.question_name;
150 nmb->additional->rr_type = nmb->question.question_type;
151 nmb->additional->rr_class = nmb->question.question_class;
153 nmb->additional->ttl = quest_type == NMB_REG ? lp_max_ttl() : 0;
154 nmb->additional->rdlength = 6;
155 nmb->additional->rdata[0] = nb_flags;
156 putip(&nmb->additional->rdata[2],(char *)iface_ip(to_ip));
159 p.ip = to_ip;
160 p.port = NMB_PORT;
161 p.fd = fd;
162 p.timestamp = time(NULL);
163 p.packet_type = NMB_PACKET;
165 if (!send_packet(&p)) *id = 0xffff;
167 return;
171 /****************************************************************************
172 reply to a netbios name packet
173 ****************************************************************************/
174 void reply_netbios_packet(struct packet_struct *p1,int trn_id,
175 int rcode, int rcv_code, int opcode, BOOL recurse,
176 struct nmb_name *rr_name,int rr_type,int rr_class,int ttl,
177 char *data,int len)
179 struct packet_struct p;
180 struct nmb_packet *nmb = &p.packet.nmb;
181 struct res_rec answers;
182 char *packet_type = "unknown";
183 BOOL recursion_desired = False;
185 p = *p1;
187 switch (rcv_code)
189 case NMB_STATUS:
191 packet_type = "nmb_status";
192 recursion_desired = True;
193 break;
195 case NMB_QUERY:
197 packet_type = "nmb_query";
198 recursion_desired = True;
199 break;
201 case NMB_REG:
203 packet_type = "nmb_reg";
204 recursion_desired = True;
205 break;
207 case NMB_REL:
209 packet_type = "nmb_rel";
210 recursion_desired = False;
211 break;
213 case NMB_WAIT_ACK:
215 packet_type = "nmb_wack";
216 recursion_desired = False;
217 break;
219 default:
221 DEBUG(1,("replying netbios packet: %s %s\n",
222 packet_type, namestr(rr_name), inet_ntoa(p.ip)));
224 return;
228 DEBUG(4,("replying netbios packet: %s %s\n",
229 packet_type, namestr(rr_name), inet_ntoa(p.ip)));
231 nmb->header.name_trn_id = trn_id;
232 nmb->header.opcode = opcode;
233 nmb->header.response = True;
234 nmb->header.nm_flags.bcast = False;
235 nmb->header.nm_flags.recursion_available = recurse;
236 nmb->header.nm_flags.recursion_desired = recursion_desired;
237 nmb->header.nm_flags.trunc = False;
238 nmb->header.nm_flags.authoritative = True;
240 nmb->header.qdcount = 0;
241 nmb->header.ancount = 1;
242 nmb->header.nscount = 0;
243 nmb->header.arcount = 0;
244 nmb->header.rcode = 0;
246 bzero((char*)&nmb->question,sizeof(nmb->question));
248 nmb->answers = &answers;
249 bzero((char*)nmb->answers,sizeof(*nmb->answers));
251 nmb->answers->rr_name = *rr_name;
252 nmb->answers->rr_type = rr_type;
253 nmb->answers->rr_class = rr_class;
254 nmb->answers->ttl = ttl;
256 if (data && len)
258 nmb->answers->rdlength = len;
259 memcpy(nmb->answers->rdata, data, len);
262 p.packet_type = NMB_PACKET;
264 debug_nmb_packet(&p);
266 send_packet(&p);
270 /*******************************************************************
271 the global packet linked-list. incoming entries are added to the
272 end of this list. it is supposed to remain fairly short so we
273 won't bother with an end pointer.
274 ******************************************************************/
275 static struct packet_struct *packet_queue = NULL;
277 /*******************************************************************
278 queue a packet into the packet queue
279 ******************************************************************/
280 void queue_packet(struct packet_struct *packet)
282 struct packet_struct *p;
284 if (!packet_queue) {
285 packet->prev = NULL;
286 packet->next = NULL;
287 packet_queue = packet;
288 return;
291 /* find the bottom */
292 for (p=packet_queue;p->next;p=p->next) ;
294 p->next = packet;
295 packet->next = NULL;
296 packet->prev = p;
300 /****************************************************************************
301 process udp 138 datagrams
302 ****************************************************************************/
303 static void process_dgram(struct packet_struct *p)
305 char *buf;
306 char *buf2;
307 int len;
308 struct dgram_packet *dgram = &p->packet.dgram;
310 if (dgram->header.msg_type != 0x10 &&
311 dgram->header.msg_type != 0x11 &&
312 dgram->header.msg_type != 0x12) {
313 /* don't process error packets etc yet */
314 return;
317 buf = &dgram->data[0];
318 buf -= 4; /* XXXX for the pseudo tcp length -
319 someday I need to get rid of this */
321 if (CVAL(buf,smb_com) != SMBtrans) return;
323 len = SVAL(buf,smb_vwv11);
324 buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
326 DEBUG(4,("datagram from %s to %s for %s of type %d len=%d\n",
327 namestr(&dgram->source_name),namestr(&dgram->dest_name),
328 smb_buf(buf),CVAL(buf2,0),len));
331 if (len <= 0) return;
333 /* datagram packet received for the browser mailslot */
334 if (strequal(smb_buf(buf),BROWSE_MAILSLOT)) {
335 process_browse_packet(p,buf2,len);
336 return;
339 /* datagram packet received for the domain log on mailslot */
340 if (strequal(smb_buf(buf),NET_LOGON_MAILSLOT)) {
341 process_logon_packet(p,buf2,len);
342 return;
346 /****************************************************************************
347 process a nmb packet
348 ****************************************************************************/
349 static void process_nmb(struct packet_struct *p)
351 struct nmb_packet *nmb = &p->packet.nmb;
353 debug_nmb_packet(p);
355 switch (nmb->header.opcode)
357 case 8: /* what is this?? */
358 case NMB_REG:
359 case NMB_REG_REFRESH:
361 if (nmb->header.qdcount==0 || nmb->header.arcount==0) break;
362 if (nmb->header.response)
363 response_netbios_packet(p); /* response to registration dealt with here */
364 else
365 reply_name_reg(p);
366 break;
369 case 0:
371 if (nmb->header.response)
373 switch (nmb->question.question_type)
375 case 0x0:
377 response_netbios_packet(p);
378 break;
381 return;
383 else if (nmb->header.qdcount>0)
385 switch (nmb->question.question_type)
387 case NMB_QUERY:
389 reply_name_query(p);
390 break;
392 case NMB_STATUS:
394 reply_name_status(p);
395 break;
398 return;
400 break;
403 case NMB_REL:
405 if (nmb->header.qdcount==0 || nmb->header.arcount==0)
407 DEBUG(2,("netbios release packet rejected\n"));
408 break;
411 if (nmb->header.response)
412 response_netbios_packet(p); /* response to reply dealt with in here */
413 else
414 reply_name_release(p);
415 break;
421 /*******************************************************************
422 run elements off the packet queue till its empty
423 ******************************************************************/
424 void run_packet_queue()
426 struct packet_struct *p;
428 while ((p=packet_queue))
430 switch (p->packet_type)
432 case NMB_PACKET:
433 process_nmb(p);
434 break;
436 case DGRAM_PACKET:
437 process_dgram(p);
438 break;
441 packet_queue = packet_queue->next;
442 if (packet_queue) packet_queue->prev = NULL;
443 free_packet(p);
447 /****************************************************************************
448 listens for NMB or DGRAM packets, and queues them
449 ***************************************************************************/
450 void listen_for_packets(BOOL run_election)
452 fd_set fds;
453 int selrtn;
454 struct timeval timeout;
456 FD_ZERO(&fds);
457 FD_SET(ClientNMB,&fds);
458 FD_SET(ClientDGRAM,&fds);
460 /* during elections and when expecting a netbios response packet we need
461 to send election packets at one second intervals.
462 XXXX actually, it needs to be the interval (in ms) between time now and the
463 time we are expecting the next netbios packet */
465 timeout.tv_sec = (run_election||num_response_packets) ? 1 : NMBD_SELECT_LOOP;
466 timeout.tv_usec = 0;
468 selrtn = sys_select(&fds,&timeout);
470 if (FD_ISSET(ClientNMB,&fds))
472 struct packet_struct *packet = read_packet(ClientNMB, NMB_PACKET);
473 if (packet) {
474 #if 1
475 if (ismyip(packet->ip) &&
476 (packet->port == NMB_PORT || packet->port == DGRAM_PORT)) {
477 DEBUG(5,("discarding own packet from %s:%d\n",
478 inet_ntoa(packet->ip),packet->port));
479 free_packet(packet);
480 } else
481 #endif
483 queue_packet(packet);
488 if (FD_ISSET(ClientDGRAM,&fds))
490 struct packet_struct *packet = read_packet(ClientDGRAM, DGRAM_PACKET);
491 if (packet) {
492 #if 1
493 if (ismyip(packet->ip) &&
494 (packet->port == NMB_PORT || packet->port == DGRAM_PORT)) {
495 DEBUG(5,("discarding own packet from %s:%d\n",
496 inet_ntoa(packet->ip),packet->port));
497 free_packet(packet);
498 } else
499 #endif
501 queue_packet(packet);
509 /****************************************************************************
510 construct and send a netbios DGRAM
512 Note that this currently sends all answers to port 138. thats the
513 wrong things to do! I should send to the requestors port. XXX
514 **************************************************************************/
515 BOOL send_mailslot_reply(char *mailslot,int fd,char *buf,int len,char *srcname,
516 char *dstname,int src_type,int dest_type,
517 struct in_addr dest_ip,struct in_addr src_ip)
519 struct packet_struct p;
520 struct dgram_packet *dgram = &p.packet.dgram;
521 struct in_addr wins_ip = ipgrp;
522 char *ptr,*p2;
523 char tmp[4];
525 /* ha ha. no. do NOT send packets to 255.255.255.255: it's a pseudo address */
526 if (ip_equal(wins_ip, dest_ip)) return False;
528 bzero((char *)&p,sizeof(p));
530 update_name_trn_id();
532 dgram->header.msg_type = 0x11; /* DIRECT GROUP DATAGRAM */
533 dgram->header.flags.node_type = M_NODE;
534 dgram->header.flags.first = True;
535 dgram->header.flags.more = False;
536 dgram->header.dgm_id = name_trn_id;
537 dgram->header.source_ip = src_ip;
538 dgram->header.source_port = DGRAM_PORT;
539 dgram->header.dgm_length = 0; /* let build_dgram() handle this */
540 dgram->header.packet_offset = 0;
542 make_nmb_name(&dgram->source_name,srcname,src_type,scope);
543 make_nmb_name(&dgram->dest_name,dstname,dest_type,scope);
545 ptr = &dgram->data[0];
547 /* now setup the smb part */
548 ptr -= 4; /* XXX ugliness because of handling of tcp SMB length */
549 memcpy(tmp,ptr,4);
550 set_message(ptr,17,17 + len,True);
551 memcpy(ptr,tmp,4);
553 CVAL(ptr,smb_com) = SMBtrans;
554 SSVAL(ptr,smb_vwv1,len);
555 SSVAL(ptr,smb_vwv11,len);
556 SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
557 SSVAL(ptr,smb_vwv13,3);
558 SSVAL(ptr,smb_vwv14,1);
559 SSVAL(ptr,smb_vwv15,1);
560 SSVAL(ptr,smb_vwv16,2);
561 p2 = smb_buf(ptr);
562 strcpy(p2,mailslot);
563 p2 = skip_string(p2,1);
565 memcpy(p2,buf,len);
566 p2 += len;
568 dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length */
570 p.ip = dest_ip;
571 p.port = DGRAM_PORT;
572 p.fd = ClientDGRAM;
573 p.timestamp = time(NULL);
574 p.packet_type = DGRAM_PACKET;
576 DEBUG(4,("send mailslot %s from %s %s", mailslot,
577 inet_ntoa(src_ip),namestr(&dgram->source_name)));
578 DEBUG(4,("to %s %s\n", inet_ntoa(dest_ip),namestr(&dgram->dest_name)));
580 return(send_packet(&p));