Fixes from Toomas Soome <tsoome@ut.ee> code unicode problems, plus
[Samba.git] / source / libsmb / nmblib.c
blob22ff09faa31a86e8c33370c0f31a3ec842979648
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
4 NBT netbios library routines
5 Copyright (C) Andrew Tridgell 1994-1998
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 #include "includes.h"
25 extern int DEBUGLEVEL;
27 int num_good_sends = 0;
28 int num_good_receives = 0;
30 static struct opcode_names {
31 char *nmb_opcode_name;
32 int opcode;
33 } nmb_header_opcode_names[] = {
34 {"Query", 0 },
35 {"Registration", 5 },
36 {"Release", 6 },
37 {"WACK", 7 },
38 {"Refresh", 8 },
39 {"Refresh(altcode)", 9 },
40 {"Multi-homed Registration", 15 },
41 {0, -1 }
44 /****************************************************************************
45 * Lookup a nmb opcode name.
46 ****************************************************************************/
47 static char *lookup_opcode_name( int opcode )
49 struct opcode_names *op_namep;
50 int i;
52 for(i = 0; nmb_header_opcode_names[i].nmb_opcode_name != 0; i++) {
53 op_namep = &nmb_header_opcode_names[i];
54 if(opcode == op_namep->opcode)
55 return op_namep->nmb_opcode_name;
57 return "<unknown opcode>";
60 /****************************************************************************
61 print out a res_rec structure
62 ****************************************************************************/
63 static void debug_nmb_res_rec(struct res_rec *res, char *hdr)
65 int i, j;
67 DEBUGADD( 4, ( " %s: nmb_name=%s rr_type=%d rr_class=%d ttl=%d\n",
68 hdr,
69 nmb_namestr(&res->rr_name),
70 res->rr_type,
71 res->rr_class,
72 res->ttl ) );
74 if( res->rdlength == 0 || res->rdata == NULL )
75 return;
77 for (i = 0; i < res->rdlength; i+= 16)
79 DEBUGADD(4, (" %s %3x char ", hdr, i));
81 for (j = 0; j < 16; j++)
83 uchar x = res->rdata[i+j];
84 if (x < 32 || x > 127) x = '.';
86 if (i+j >= res->rdlength) break;
87 DEBUGADD(4, ("%c", x));
90 DEBUGADD(4, (" hex "));
92 for (j = 0; j < 16; j++)
94 if (i+j >= res->rdlength) break;
95 DEBUGADD(4, ("%02X", (uchar)res->rdata[i+j]));
98 DEBUGADD(4, ("\n"));
102 /****************************************************************************
103 process a nmb packet
104 ****************************************************************************/
105 void debug_nmb_packet(struct packet_struct *p)
107 struct nmb_packet *nmb = &p->packet.nmb;
109 if( DEBUGLVL( 4 ) )
111 dbgtext( "nmb packet from %s(%d) header: id=%d opcode=%s(%d) response=%s\n",
112 inet_ntoa(p->ip), p->port,
113 nmb->header.name_trn_id,
114 lookup_opcode_name(nmb->header.opcode),
115 nmb->header.opcode,
116 BOOLSTR(nmb->header.response) );
117 dbgtext( " header: flags: bcast=%s rec_avail=%s rec_des=%s trunc=%s auth=%s\n",
118 BOOLSTR(nmb->header.nm_flags.bcast),
119 BOOLSTR(nmb->header.nm_flags.recursion_available),
120 BOOLSTR(nmb->header.nm_flags.recursion_desired),
121 BOOLSTR(nmb->header.nm_flags.trunc),
122 BOOLSTR(nmb->header.nm_flags.authoritative) );
123 dbgtext( " header: rcode=%d qdcount=%d ancount=%d nscount=%d arcount=%d\n",
124 nmb->header.rcode,
125 nmb->header.qdcount,
126 nmb->header.ancount,
127 nmb->header.nscount,
128 nmb->header.arcount );
131 if (nmb->header.qdcount)
133 DEBUGADD( 4, ( " question: q_name=%s q_type=%d q_class=%d\n",
134 nmb_namestr(&nmb->question.question_name),
135 nmb->question.question_type,
136 nmb->question.question_class) );
139 if (nmb->answers && nmb->header.ancount)
141 debug_nmb_res_rec(nmb->answers,"answers");
143 if (nmb->nsrecs && nmb->header.nscount)
145 debug_nmb_res_rec(nmb->nsrecs,"nsrecs");
147 if (nmb->additional && nmb->header.arcount)
149 debug_nmb_res_rec(nmb->additional,"additional");
153 /*******************************************************************
154 handle "compressed" name pointers
155 ******************************************************************/
156 static BOOL handle_name_ptrs(uchar *ubuf,int *offset,int length,
157 BOOL *got_pointer,int *ret)
159 int loop_count=0;
161 while ((ubuf[*offset] & 0xC0) == 0xC0) {
162 if (!*got_pointer) (*ret) += 2;
163 (*got_pointer)=True;
164 (*offset) = ((ubuf[*offset] & ~0xC0)<<8) | ubuf[(*offset)+1];
165 if (loop_count++ == 10 || (*offset) < 0 || (*offset)>(length-2)) {
166 return(False);
169 return(True);
172 /*******************************************************************
173 parse a nmb name from "compressed" format to something readable
174 return the space taken by the name, or 0 if the name is invalid
175 ******************************************************************/
176 static int parse_nmb_name(char *inbuf,int offset,int length, struct nmb_name *name)
178 int m,n=0;
179 uchar *ubuf = (uchar *)inbuf;
180 int ret = 0;
181 BOOL got_pointer=False;
182 int loop_count=0;
184 if (length - offset < 2)
185 return(0);
187 /* handle initial name pointers */
188 if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret))
189 return(0);
191 m = ubuf[offset];
193 if (!m)
194 return(0);
195 if ((m & 0xC0) || offset+m+2 > length)
196 return(0);
198 memset((char *)name,'\0',sizeof(*name));
200 /* the "compressed" part */
201 if (!got_pointer)
202 ret += m + 2;
203 offset++;
204 while (m > 0) {
205 uchar c1,c2;
206 c1 = ubuf[offset++]-'A';
207 c2 = ubuf[offset++]-'A';
208 if ((c1 & 0xF0) || (c2 & 0xF0) || (n > sizeof(name->name)-1))
209 return(0);
210 name->name[n++] = (c1<<4) | c2;
211 m -= 2;
213 name->name[n] = 0;
215 if (n==16) {
216 /* parse out the name type,
217 its always in the 16th byte of the name */
218 name->name_type = ((uchar)name->name[15]) & 0xff;
220 /* remove trailing spaces */
221 name->name[15] = 0;
222 n = 14;
223 while (n && name->name[n]==' ')
224 name->name[n--] = 0;
227 /* now the domain parts (if any) */
228 n = 0;
229 while (ubuf[offset]) {
230 /* we can have pointers within the domain part as well */
231 if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret))
232 return(0);
234 m = ubuf[offset];
236 * Don't allow null domain parts.
238 if (!m)
239 return(0);
240 if (!got_pointer)
241 ret += m+1;
242 if (n)
243 name->scope[n++] = '.';
244 if (m+2+offset>length || n+m+1>sizeof(name->scope))
245 return(0);
246 offset++;
247 while (m--)
248 name->scope[n++] = (char)ubuf[offset++];
251 * Watch for malicious loops.
253 if (loop_count++ == 10)
254 return 0;
256 name->scope[n++] = 0;
258 return(ret);
262 /*******************************************************************
263 put a compressed nmb name into a buffer. return the length of the
264 compressed name
266 compressed names are really weird. The "compression" doubles the
267 size. The idea is that it also means that compressed names conform
268 to the doman name system. See RFC1002.
269 ******************************************************************/
270 static int put_nmb_name(char *buf,int offset,struct nmb_name *name)
272 int ret,m;
273 fstring buf1;
274 char *p;
276 if (strcmp(name->name,"*") == 0) {
277 /* special case for wildcard name */
278 memset(buf1,'\0',20);
279 buf1[0] = '*';
280 buf1[15] = name->name_type;
281 } else {
282 slprintf(buf1, sizeof(buf1) - 1,"%-15.15s%c",name->name,name->name_type);
285 buf[offset] = 0x20;
287 ret = 34;
289 for (m=0;m<16;m++) {
290 buf[offset+1+2*m] = 'A' + ((buf1[m]>>4)&0xF);
291 buf[offset+2+2*m] = 'A' + (buf1[m]&0xF);
293 offset += 33;
295 buf[offset] = 0;
297 if (name->scope[0]) {
298 /* XXXX this scope handling needs testing */
299 ret += strlen(name->scope) + 1;
300 pstrcpy(&buf[offset+1],name->scope);
302 p = &buf[offset+1];
303 while ((p = strchr(p,'.'))) {
304 buf[offset] = PTR_DIFF(p,&buf[offset+1]);
305 offset += (buf[offset] + 1);
306 p = &buf[offset+1];
308 buf[offset] = strlen(&buf[offset+1]);
311 return(ret);
314 /*******************************************************************
315 useful for debugging messages
316 ******************************************************************/
317 char *nmb_namestr(struct nmb_name *n)
319 static int i=0;
320 static fstring ret[4];
321 char *p = ret[i];
323 if (!n->scope[0])
324 slprintf(p,sizeof(fstring)-1, "%s<%02x>",n->name,n->name_type);
325 else
326 slprintf(p,sizeof(fstring)-1, "%s<%02x>.%s",n->name,n->name_type,n->scope);
328 i = (i+1)%4;
329 return(p);
332 /*******************************************************************
333 allocate and parse some resource records
334 ******************************************************************/
335 static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length,
336 struct res_rec **recs, int count)
338 int i;
339 *recs = (struct res_rec *)malloc(sizeof(**recs)*count);
340 if (!*recs) return(False);
342 memset((char *)*recs,'\0',sizeof(**recs)*count);
344 for (i=0;i<count;i++) {
345 int l = parse_nmb_name(inbuf,*offset,length,&(*recs)[i].rr_name);
346 (*offset) += l;
347 if (!l || (*offset)+10 > length) {
348 free(*recs);
349 *recs = NULL;
350 return(False);
352 (*recs)[i].rr_type = RSVAL(inbuf,(*offset));
353 (*recs)[i].rr_class = RSVAL(inbuf,(*offset)+2);
354 (*recs)[i].ttl = RIVAL(inbuf,(*offset)+4);
355 (*recs)[i].rdlength = RSVAL(inbuf,(*offset)+8);
356 (*offset) += 10;
357 if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) ||
358 (*offset)+(*recs)[i].rdlength > length) {
359 free(*recs);
360 *recs = NULL;
361 return(False);
363 memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength);
364 (*offset) += (*recs)[i].rdlength;
366 return(True);
369 /*******************************************************************
370 put a resource record into a packet
371 ******************************************************************/
372 static int put_res_rec(char *buf,int offset,struct res_rec *recs,int count)
374 int ret=0;
375 int i;
377 for (i=0;i<count;i++) {
378 int l = put_nmb_name(buf,offset,&recs[i].rr_name);
379 offset += l;
380 ret += l;
381 RSSVAL(buf,offset,recs[i].rr_type);
382 RSSVAL(buf,offset+2,recs[i].rr_class);
383 RSIVAL(buf,offset+4,recs[i].ttl);
384 RSSVAL(buf,offset+8,recs[i].rdlength);
385 memcpy(buf+offset+10,recs[i].rdata,recs[i].rdlength);
386 offset += 10+recs[i].rdlength;
387 ret += 10+recs[i].rdlength;
390 return(ret);
393 /*******************************************************************
394 put a compressed name pointer record into a packet
395 ******************************************************************/
396 static int put_compressed_name_ptr(uchar *buf,int offset,struct res_rec *rec,int ptr_offset)
398 int ret=0;
399 buf[offset] = (0xC0 | ((ptr_offset >> 8) & 0xFF));
400 buf[offset+1] = (ptr_offset & 0xFF);
401 offset += 2;
402 ret += 2;
403 RSSVAL(buf,offset,rec->rr_type);
404 RSSVAL(buf,offset+2,rec->rr_class);
405 RSIVAL(buf,offset+4,rec->ttl);
406 RSSVAL(buf,offset+8,rec->rdlength);
407 memcpy(buf+offset+10,rec->rdata,rec->rdlength);
408 offset += 10+rec->rdlength;
409 ret += 10+rec->rdlength;
411 return(ret);
414 /*******************************************************************
415 parse a dgram packet. Return False if the packet can't be parsed
416 or is invalid for some reason, True otherwise
418 this is documented in section 4.4.1 of RFC1002
419 ******************************************************************/
420 static BOOL parse_dgram(char *inbuf,int length,struct dgram_packet *dgram)
422 int offset;
423 int flags;
425 memset((char *)dgram,'\0',sizeof(*dgram));
427 if (length < 14) return(False);
429 dgram->header.msg_type = CVAL(inbuf,0);
430 flags = CVAL(inbuf,1);
431 dgram->header.flags.node_type = (enum node_type)((flags>>2)&3);
432 if (flags & 1) dgram->header.flags.more = True;
433 if (flags & 2) dgram->header.flags.first = True;
434 dgram->header.dgm_id = RSVAL(inbuf,2);
435 putip((char *)&dgram->header.source_ip,inbuf+4);
436 dgram->header.source_port = RSVAL(inbuf,8);
437 dgram->header.dgm_length = RSVAL(inbuf,10);
438 dgram->header.packet_offset = RSVAL(inbuf,12);
440 offset = 14;
442 if (dgram->header.msg_type == 0x10 ||
443 dgram->header.msg_type == 0x11 ||
444 dgram->header.msg_type == 0x12) {
445 offset += parse_nmb_name(inbuf,offset,length,&dgram->source_name);
446 offset += parse_nmb_name(inbuf,offset,length,&dgram->dest_name);
449 if (offset >= length || (length-offset > sizeof(dgram->data)))
450 return(False);
452 dgram->datasize = length-offset;
453 memcpy(dgram->data,inbuf+offset,dgram->datasize);
455 return(True);
459 /*******************************************************************
460 parse a nmb packet. Return False if the packet can't be parsed
461 or is invalid for some reason, True otherwise
462 ******************************************************************/
463 static BOOL parse_nmb(char *inbuf,int length,struct nmb_packet *nmb)
465 int nm_flags,offset;
467 memset((char *)nmb,'\0',sizeof(*nmb));
469 if (length < 12) return(False);
471 /* parse the header */
472 nmb->header.name_trn_id = RSVAL(inbuf,0);
474 DEBUG(10,("parse_nmb: packet id = %d\n", nmb->header.name_trn_id));
476 nmb->header.opcode = (CVAL(inbuf,2) >> 3) & 0xF;
477 nmb->header.response = ((CVAL(inbuf,2)>>7)&1)?True:False;
478 nm_flags = ((CVAL(inbuf,2) & 0x7) << 4) + (CVAL(inbuf,3)>>4);
479 nmb->header.nm_flags.bcast = (nm_flags&1)?True:False;
480 nmb->header.nm_flags.recursion_available = (nm_flags&8)?True:False;
481 nmb->header.nm_flags.recursion_desired = (nm_flags&0x10)?True:False;
482 nmb->header.nm_flags.trunc = (nm_flags&0x20)?True:False;
483 nmb->header.nm_flags.authoritative = (nm_flags&0x40)?True:False;
484 nmb->header.rcode = CVAL(inbuf,3) & 0xF;
485 nmb->header.qdcount = RSVAL(inbuf,4);
486 nmb->header.ancount = RSVAL(inbuf,6);
487 nmb->header.nscount = RSVAL(inbuf,8);
488 nmb->header.arcount = RSVAL(inbuf,10);
490 if (nmb->header.qdcount) {
491 offset = parse_nmb_name(inbuf,12,length,&nmb->question.question_name);
492 if (!offset) return(False);
494 if (length - (12+offset) < 4) return(False);
495 nmb->question.question_type = RSVAL(inbuf,12+offset);
496 nmb->question.question_class = RSVAL(inbuf,12+offset+2);
498 offset += 12+4;
499 } else {
500 offset = 12;
503 /* and any resource records */
504 if (nmb->header.ancount &&
505 !parse_alloc_res_rec(inbuf,&offset,length,&nmb->answers,
506 nmb->header.ancount))
507 return(False);
509 if (nmb->header.nscount &&
510 !parse_alloc_res_rec(inbuf,&offset,length,&nmb->nsrecs,
511 nmb->header.nscount))
512 return(False);
514 if (nmb->header.arcount &&
515 !parse_alloc_res_rec(inbuf,&offset,length,&nmb->additional,
516 nmb->header.arcount))
517 return(False);
519 return(True);
522 /*******************************************************************
523 'Copy constructor' for an nmb packet
524 ******************************************************************/
525 static struct packet_struct *copy_nmb_packet(struct packet_struct *packet)
527 struct nmb_packet *nmb;
528 struct nmb_packet *copy_nmb;
529 struct packet_struct *pkt_copy;
531 if(( pkt_copy = (struct packet_struct *)malloc(sizeof(*packet))) == NULL)
533 DEBUG(0,("copy_nmb_packet: malloc fail.\n"));
534 return NULL;
537 /* Structure copy of entire thing. */
539 *pkt_copy = *packet;
541 /* Ensure this copy is not locked. */
542 pkt_copy->locked = False;
544 /* Ensure this copy has no resource records. */
545 nmb = &packet->packet.nmb;
546 copy_nmb = &pkt_copy->packet.nmb;
548 copy_nmb->answers = NULL;
549 copy_nmb->nsrecs = NULL;
550 copy_nmb->additional = NULL;
552 /* Now copy any resource records. */
554 if (nmb->answers)
556 if((copy_nmb->answers = (struct res_rec *)
557 malloc(nmb->header.ancount * sizeof(struct res_rec))) == NULL)
558 goto free_and_exit;
559 memcpy((char *)copy_nmb->answers, (char *)nmb->answers,
560 nmb->header.ancount * sizeof(struct res_rec));
562 if (nmb->nsrecs)
564 if((copy_nmb->nsrecs = (struct res_rec *)
565 malloc(nmb->header.nscount * sizeof(struct res_rec))) == NULL)
566 goto free_and_exit;
567 memcpy((char *)copy_nmb->nsrecs, (char *)nmb->nsrecs,
568 nmb->header.nscount * sizeof(struct res_rec));
570 if (nmb->additional)
572 if((copy_nmb->additional = (struct res_rec *)
573 malloc(nmb->header.arcount * sizeof(struct res_rec))) == NULL)
574 goto free_and_exit;
575 memcpy((char *)copy_nmb->additional, (char *)nmb->additional,
576 nmb->header.arcount * sizeof(struct res_rec));
579 return pkt_copy;
581 free_and_exit:
583 if(copy_nmb->answers) {
584 free((char *)copy_nmb->answers);
585 copy_nmb->answers = NULL;
587 if(copy_nmb->nsrecs) {
588 free((char *)copy_nmb->nsrecs);
589 copy_nmb->nsrecs = NULL;
591 if(copy_nmb->additional) {
592 free((char *)copy_nmb->additional);
593 copy_nmb->additional = NULL;
595 free((char *)pkt_copy);
597 DEBUG(0,("copy_nmb_packet: malloc fail in resource records.\n"));
598 return NULL;
601 /*******************************************************************
602 'Copy constructor' for a dgram packet
603 ******************************************************************/
604 static struct packet_struct *copy_dgram_packet(struct packet_struct *packet)
606 struct packet_struct *pkt_copy;
608 if(( pkt_copy = (struct packet_struct *)malloc(sizeof(*packet))) == NULL)
610 DEBUG(0,("copy_dgram_packet: malloc fail.\n"));
611 return NULL;
614 /* Structure copy of entire thing. */
616 *pkt_copy = *packet;
618 /* Ensure this copy is not locked. */
619 pkt_copy->locked = False;
621 /* There are no additional pointers in a dgram packet,
622 we are finished. */
623 return pkt_copy;
626 /*******************************************************************
627 'Copy constructor' for a generic packet
628 ******************************************************************/
629 struct packet_struct *copy_packet(struct packet_struct *packet)
631 if(packet->packet_type == NMB_PACKET)
632 return copy_nmb_packet(packet);
633 else if (packet->packet_type == DGRAM_PACKET)
634 return copy_dgram_packet(packet);
635 return NULL;
638 /*******************************************************************
639 free up any resources associated with an nmb packet
640 ******************************************************************/
641 static void free_nmb_packet(struct nmb_packet *nmb)
643 if (nmb->answers) {
644 free(nmb->answers);
645 nmb->answers = NULL;
647 if (nmb->nsrecs) {
648 free(nmb->nsrecs);
649 nmb->nsrecs = NULL;
651 if (nmb->additional) {
652 free(nmb->additional);
653 nmb->additional = NULL;
657 /*******************************************************************
658 free up any resources associated with a dgram packet
659 ******************************************************************/
660 static void free_dgram_packet(struct dgram_packet *nmb)
662 /* We have nothing to do for a dgram packet. */
665 /*******************************************************************
666 free up any resources associated with a packet
667 ******************************************************************/
668 void free_packet(struct packet_struct *packet)
670 if (packet->locked)
671 return;
672 if (packet->packet_type == NMB_PACKET)
673 free_nmb_packet(&packet->packet.nmb);
674 else if (packet->packet_type == DGRAM_PACKET)
675 free_dgram_packet(&packet->packet.dgram);
676 ZERO_STRUCTPN(packet);
677 free(packet);
680 /*******************************************************************
681 parse a packet buffer into a packet structure
682 ******************************************************************/
683 struct packet_struct *parse_packet(char *buf,int length,
684 enum packet_type packet_type)
686 extern struct in_addr lastip;
687 extern int lastport;
688 struct packet_struct *p;
689 BOOL ok=False;
691 p = (struct packet_struct *)malloc(sizeof(*p));
692 if (!p) return(NULL);
694 p->next = NULL;
695 p->prev = NULL;
696 p->ip = lastip;
697 p->port = lastport;
698 p->locked = False;
699 p->timestamp = time(NULL);
700 p->packet_type = packet_type;
702 switch (packet_type) {
703 case NMB_PACKET:
704 ok = parse_nmb(buf,length,&p->packet.nmb);
705 break;
707 case DGRAM_PACKET:
708 ok = parse_dgram(buf,length,&p->packet.dgram);
709 break;
712 if (!ok) {
713 free_packet(p);
714 return NULL;
717 return p;
720 /*******************************************************************
721 read a packet from a socket and parse it, returning a packet ready
722 to be used or put on the queue. This assumes a UDP socket
723 ******************************************************************/
724 struct packet_struct *read_packet(int fd,enum packet_type packet_type)
726 struct packet_struct *packet;
727 char buf[MAX_DGRAM_SIZE];
728 int length;
730 length = read_udp_socket(fd,buf,sizeof(buf));
731 if (length < MIN_DGRAM_SIZE) return(NULL);
733 packet = parse_packet(buf, length, packet_type);
734 if (!packet) return NULL;
736 packet->fd = fd;
738 num_good_receives++;
740 DEBUG(5,("Received a packet of len %d from (%s) port %d\n",
741 length, inet_ntoa(packet->ip), packet->port ) );
743 return(packet);
747 /*******************************************************************
748 send a udp packet on a already open socket
749 ******************************************************************/
750 static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port)
752 BOOL ret;
753 int i;
754 struct sockaddr_in sock_out;
756 /* set the address and port */
757 memset((char *)&sock_out,'\0',sizeof(sock_out));
758 putip((char *)&sock_out.sin_addr,(char *)&ip);
759 sock_out.sin_port = htons( port );
760 sock_out.sin_family = AF_INET;
762 DEBUG( 5, ( "Sending a packet of len %d to (%s) on port %d\n",
763 len, inet_ntoa(ip), port ) );
766 * Patch to fix asynch error notifications from Linux kernel.
769 for (i = 0; i < 5; i++) {
770 ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out, sizeof(sock_out)) >= 0);
771 if (ret || errno != ECONNREFUSED)
772 break;
775 if (!ret)
776 DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n",
777 inet_ntoa(ip),port,strerror(errno)));
779 if (ret)
780 num_good_sends++;
782 return(ret);
785 /*******************************************************************
786 build a dgram packet ready for sending
788 XXXX This currently doesn't handle packets too big for one
789 datagram. It should split them and use the packet_offset, more and
790 first flags to handle the fragmentation. Yuck.
791 ******************************************************************/
792 static int build_dgram(char *buf,struct packet_struct *p)
794 struct dgram_packet *dgram = &p->packet.dgram;
795 uchar *ubuf = (uchar *)buf;
796 int offset=0;
798 /* put in the header */
799 ubuf[0] = dgram->header.msg_type;
800 ubuf[1] = (((int)dgram->header.flags.node_type)<<2);
801 if (dgram->header.flags.more) ubuf[1] |= 1;
802 if (dgram->header.flags.first) ubuf[1] |= 2;
803 RSSVAL(ubuf,2,dgram->header.dgm_id);
804 putip(ubuf+4,(char *)&dgram->header.source_ip);
805 RSSVAL(ubuf,8,dgram->header.source_port);
806 RSSVAL(ubuf,12,dgram->header.packet_offset);
808 offset = 14;
810 if (dgram->header.msg_type == 0x10 ||
811 dgram->header.msg_type == 0x11 ||
812 dgram->header.msg_type == 0x12) {
813 offset += put_nmb_name((char *)ubuf,offset,&dgram->source_name);
814 offset += put_nmb_name((char *)ubuf,offset,&dgram->dest_name);
817 memcpy(ubuf+offset,dgram->data,dgram->datasize);
818 offset += dgram->datasize;
820 /* automatically set the dgm_length */
821 dgram->header.dgm_length = offset;
822 RSSVAL(ubuf,10,dgram->header.dgm_length);
824 return(offset);
827 /*******************************************************************
828 build a nmb name
829 *******************************************************************/
830 void make_nmb_name( struct nmb_name *n, const char *name, int type)
832 extern pstring global_scope;
833 memset( (char *)n, '\0', sizeof(struct nmb_name) );
834 StrnCpy( n->name, name, 15 );
835 unix_to_dos(n->name, True);
836 strupper( n->name );
837 n->name_type = (unsigned int)type & 0xFF;
838 StrnCpy( n->scope, global_scope, 63 );
839 strupper( n->scope );
842 /*******************************************************************
843 Compare two nmb names
844 ******************************************************************/
846 BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2)
848 return ((n1->name_type == n2->name_type) &&
849 strequal(n1->name ,n2->name ) &&
850 strequal(n1->scope,n2->scope));
853 /*******************************************************************
854 build a nmb packet ready for sending
856 XXXX this currently relies on not being passed something that expands
857 to a packet too big for the buffer. Eventually this should be
858 changed to set the trunc bit so the receiver can request the rest
859 via tcp (when that becomes supported)
860 ******************************************************************/
861 static int build_nmb(char *buf,struct packet_struct *p)
863 struct nmb_packet *nmb = &p->packet.nmb;
864 uchar *ubuf = (uchar *)buf;
865 int offset=0;
867 /* put in the header */
868 RSSVAL(ubuf,offset,nmb->header.name_trn_id);
869 ubuf[offset+2] = (nmb->header.opcode & 0xF) << 3;
870 if (nmb->header.response) ubuf[offset+2] |= (1<<7);
871 if (nmb->header.nm_flags.authoritative &&
872 nmb->header.response) ubuf[offset+2] |= 0x4;
873 if (nmb->header.nm_flags.trunc) ubuf[offset+2] |= 0x2;
874 if (nmb->header.nm_flags.recursion_desired) ubuf[offset+2] |= 0x1;
875 if (nmb->header.nm_flags.recursion_available &&
876 nmb->header.response) ubuf[offset+3] |= 0x80;
877 if (nmb->header.nm_flags.bcast) ubuf[offset+3] |= 0x10;
878 ubuf[offset+3] |= (nmb->header.rcode & 0xF);
880 RSSVAL(ubuf,offset+4,nmb->header.qdcount);
881 RSSVAL(ubuf,offset+6,nmb->header.ancount);
882 RSSVAL(ubuf,offset+8,nmb->header.nscount);
883 RSSVAL(ubuf,offset+10,nmb->header.arcount);
885 offset += 12;
886 if (nmb->header.qdcount) {
887 /* XXXX this doesn't handle a qdcount of > 1 */
888 offset += put_nmb_name((char *)ubuf,offset,&nmb->question.question_name);
889 RSSVAL(ubuf,offset,nmb->question.question_type);
890 RSSVAL(ubuf,offset+2,nmb->question.question_class);
891 offset += 4;
894 if (nmb->header.ancount)
895 offset += put_res_rec((char *)ubuf,offset,nmb->answers,
896 nmb->header.ancount);
898 if (nmb->header.nscount)
899 offset += put_res_rec((char *)ubuf,offset,nmb->nsrecs,
900 nmb->header.nscount);
903 * The spec says we must put compressed name pointers
904 * in the following outgoing packets :
905 * NAME_REGISTRATION_REQUEST, NAME_REFRESH_REQUEST,
906 * NAME_RELEASE_REQUEST.
909 if((nmb->header.response == False) &&
910 ((nmb->header.opcode == NMB_NAME_REG_OPCODE) ||
911 (nmb->header.opcode == NMB_NAME_RELEASE_OPCODE) ||
912 (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_8) ||
913 (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_9) ||
914 (nmb->header.opcode == NMB_NAME_MULTIHOMED_REG_OPCODE)) &&
915 (nmb->header.arcount == 1)) {
917 offset += put_compressed_name_ptr(ubuf,offset,nmb->additional,12);
919 } else if (nmb->header.arcount) {
920 offset += put_res_rec((char *)ubuf,offset,nmb->additional,
921 nmb->header.arcount);
923 return(offset);
927 /*******************************************************************
928 linearise a packet
929 ******************************************************************/
930 int build_packet(char *buf, struct packet_struct *p)
932 int len = 0;
934 switch (p->packet_type) {
935 case NMB_PACKET:
936 len = build_nmb(buf,p);
937 break;
939 case DGRAM_PACKET:
940 len = build_dgram(buf,p);
941 break;
944 return len;
947 /*******************************************************************
948 send a packet_struct
949 ******************************************************************/
950 BOOL send_packet(struct packet_struct *p)
952 char buf[1024];
953 int len=0;
955 memset(buf,'\0',sizeof(buf));
957 len = build_packet(buf, p);
959 if (!len) return(False);
961 return(send_udp(p->fd,buf,len,p->ip,p->port));
964 /****************************************************************************
965 receive a packet with timeout on a open UDP filedescriptor
966 The timeout is in milliseconds
967 ***************************************************************************/
968 struct packet_struct *receive_packet(int fd,enum packet_type type,int t)
970 fd_set fds;
971 struct timeval timeout;
972 int ret;
974 FD_ZERO(&fds);
975 FD_SET(fd,&fds);
976 timeout.tv_sec = t/1000;
977 timeout.tv_usec = 1000*(t%1000);
979 if ((ret = sys_select_intr(fd+1,&fds,&timeout)) == -1) {
980 /* errno should be EBADF or EINVAL. */
981 DEBUG(0,("select returned -1, errno = %s (%d)\n", strerror(errno), errno));
982 return NULL;
985 if (ret == 0) /* timeout */
986 return NULL;
988 if (FD_ISSET(fd,&fds))
989 return(read_packet(fd,type));
991 return(NULL);
995 /****************************************************************************
996 receive a UDP/137 packet either via UDP or from the unexpected packet
997 queue. The packet must be a reply packet and have the specified trn_id
998 The timeout is in milliseconds
999 ***************************************************************************/
1000 struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id)
1002 struct packet_struct *p;
1004 p = receive_packet(fd, NMB_PACKET, t);
1006 if (p && p->packet.nmb.header.response &&
1007 p->packet.nmb.header.name_trn_id == trn_id) {
1008 return p;
1010 if (p) free_packet(p);
1012 /* try the unexpected packet queue */
1013 return receive_unexpected(NMB_PACKET, trn_id, NULL);
1016 /****************************************************************************
1017 receive a UDP/138 packet either via UDP or from the unexpected packet
1018 queue. The packet must be a reply packet and have the specified mailslot name
1019 The timeout is in milliseconds
1020 ***************************************************************************/
1021 struct packet_struct *receive_dgram_packet(int fd, int t, char *mailslot_name)
1023 struct packet_struct *p;
1025 p = receive_packet(fd, DGRAM_PACKET, t);
1027 if (p && match_mailslot_name(p, mailslot_name)) {
1028 return p;
1030 if (p) free_packet(p);
1032 /* try the unexpected packet queue */
1033 return receive_unexpected(DGRAM_PACKET, 0, mailslot_name);
1037 /****************************************************************************
1038 see if a datagram has the right mailslot name
1039 ***************************************************************************/
1040 BOOL match_mailslot_name(struct packet_struct *p, char *mailslot_name)
1042 struct dgram_packet *dgram = &p->packet.dgram;
1043 char *buf;
1045 buf = &dgram->data[0];
1046 buf -= 4;
1048 buf = smb_buf(buf);
1050 if (memcmp(buf, mailslot_name, strlen(mailslot_name)+1) == 0) {
1051 return True;
1054 return False;
1058 /****************************************************************************
1059 return the number of bits that match between two 4 character buffers
1060 ***************************************************************************/
1061 static int matching_bits(uchar *p1, uchar *p2)
1063 int i, j, ret = 0;
1064 for (i=0; i<4; i++) {
1065 if (p1[i] != p2[i]) break;
1066 ret += 8;
1069 if (i==4) return ret;
1071 for (j=0; j<8; j++) {
1072 if ((p1[i] & (1<<(7-j))) != (p2[i] & (1<<(7-j)))) break;
1073 ret++;
1076 return ret;
1080 static uchar sort_ip[4];
1082 /****************************************************************************
1083 compare two query reply records
1084 ***************************************************************************/
1085 static int name_query_comp(uchar *p1, uchar *p2)
1087 return matching_bits(p2+2, sort_ip) - matching_bits(p1+2, sort_ip);
1090 /****************************************************************************
1091 sort a set of 6 byte name query response records so that the IPs that
1092 have the most leading bits in common with the specified address come first
1093 ***************************************************************************/
1094 void sort_query_replies(char *data, int n, struct in_addr ip)
1096 if (n <= 1) return;
1098 putip(sort_ip, (char *)&ip);
1100 qsort(data, n, 6, QSORT_CAST name_query_comp);
1104 #define TRUNCATE_NETBIOS_NAME 1
1106 /*******************************************************************
1107 convert, possibly using a stupid microsoft-ism which has destroyed
1108 the transport independence of netbios (for CIFS vendors that usually
1109 use the Win95-type methods, not for NT to NT communication, which uses
1110 DCE/RPC and therefore full-length unicode strings...) a dns name into
1111 a netbios name.
1113 the netbios name (NOT necessarily null-terminated) is truncated to 15
1114 characters.
1116 ******************************************************************/
1117 char *dns_to_netbios_name(char *dns_name)
1119 static char netbios_name[16];
1120 int i;
1121 StrnCpy(netbios_name, dns_name, 15);
1122 netbios_name[15] = 0;
1124 #ifdef TRUNCATE_NETBIOS_NAME
1125 /* ok. this is because of a stupid microsoft-ism. if the called host
1126 name contains a '.', microsoft clients expect you to truncate the
1127 netbios name up to and including the '.' this even applies, by
1128 mistake, to workgroup (domain) names, which is _really_ daft.
1130 for (i = 15; i >= 0; i--)
1132 if (netbios_name[i] == '.')
1134 netbios_name[i] = 0;
1135 break;
1138 #endif /* TRUNCATE_NETBIOS_NAME */
1140 return netbios_name;
1144 /****************************************************************************
1145 interpret the weird netbios "name". Return the name type
1146 ****************************************************************************/
1147 static int name_interpret(char *in,char *out)
1149 int ret;
1150 int len = (*in++) / 2;
1152 *out=0;
1154 if (len > 30 || len<1) return(0);
1156 while (len--)
1158 if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
1159 *out = 0;
1160 return(0);
1162 *out = ((in[0]-'A')<<4) + (in[1]-'A');
1163 in += 2;
1164 out++;
1166 *out = 0;
1167 ret = out[-1];
1169 #ifdef NETBIOS_SCOPE
1170 /* Handle any scope names */
1171 while(*in)
1173 *out++ = '.'; /* Scope names are separated by periods */
1174 len = *(uchar *)in++;
1175 StrnCpy(out, in, len);
1176 out += len;
1177 *out=0;
1178 in += len;
1180 #endif
1181 return(ret);
1184 /****************************************************************************
1185 mangle a name into netbios format
1187 Note: <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
1188 ****************************************************************************/
1189 int name_mangle( char *In, char *Out, char name_type )
1191 int i;
1192 int c;
1193 int len;
1194 char buf[20];
1195 char *p = Out;
1196 extern pstring global_scope;
1198 /* Safely copy the input string, In, into buf[]. */
1199 (void)memset( buf, 0, 20 );
1200 if (strcmp(In,"*") == 0)
1201 buf[0] = '*';
1202 else
1203 (void)slprintf( buf, sizeof(buf) - 1, "%-15.15s%c", In, name_type );
1205 /* Place the length of the first field into the output buffer. */
1206 p[0] = 32;
1207 p++;
1209 /* Now convert the name to the rfc1001/1002 format. */
1210 for( i = 0; i < 16; i++ )
1212 c = toupper( buf[i] );
1213 p[i*2] = ( (c >> 4) & 0x000F ) + 'A';
1214 p[(i*2)+1] = (c & 0x000F) + 'A';
1216 p += 32;
1217 p[0] = '\0';
1219 /* Add the scope string. */
1220 for( i = 0, len = 0; NULL != global_scope; i++, len++ )
1222 switch( global_scope[i] )
1224 case '\0':
1225 p[0] = len;
1226 if( len > 0 )
1227 p[len+1] = 0;
1228 return( name_len(Out) );
1229 case '.':
1230 p[0] = len;
1231 p += (len + 1);
1232 len = -1;
1233 break;
1234 default:
1235 p[len+1] = global_scope[i];
1236 break;
1240 return( name_len(Out) );
1241 } /* name_mangle */
1244 /****************************************************************************
1245 find a pointer to a netbios name
1246 ****************************************************************************/
1247 static char *name_ptr(char *buf,int ofs)
1249 uchar c = *(uchar *)(buf+ofs);
1251 if ((c & 0xC0) == 0xC0)
1253 uint16 l = RSVAL(buf, ofs) & 0x3FFF;
1254 DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
1255 return(buf + l);
1257 else
1258 return(buf+ofs);
1261 /****************************************************************************
1262 extract a netbios name from a buf
1263 ****************************************************************************/
1264 int name_extract(char *buf,int ofs,char *name)
1266 char *p = name_ptr(buf,ofs);
1267 int d = PTR_DIFF(p,buf+ofs);
1268 pstrcpy(name,"");
1269 if (d < -50 || d > 50) return(0);
1270 return(name_interpret(p,name));
1273 /****************************************************************************
1274 return the total storage length of a mangled name
1275 ****************************************************************************/
1276 int name_len(char *s1)
1278 /* NOTE: this argument _must_ be unsigned */
1279 uchar *s = (uchar *)s1;
1280 int len;
1282 /* If the two high bits of the byte are set, return 2. */
1283 if (0xC0 == (*s & 0xC0))
1284 return(2);
1286 /* Add up the length bytes. */
1287 for (len = 1; (*s); s += (*s) + 1) {
1288 len += *s + 1;
1289 SMB_ASSERT(len < 80);
1292 return(len);
1293 } /* name_len */