More GUID->struct uuid changes.
[Samba/gebeck_regimport.git] / source / libsmb / nmblib.c
blobff38245435dcbb09753488d6a97a7cd3a46c179b
1 /*
2 Unix SMB/CIFS implementation.
3 NBT netbios library routines
4 Copyright (C) Andrew Tridgell 1994-1998
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "includes.h"
24 int num_good_sends = 0;
25 int num_good_receives = 0;
27 static const struct opcode_names {
28 const char *nmb_opcode_name;
29 int opcode;
30 } nmb_header_opcode_names[] = {
31 {"Query", 0 },
32 {"Registration", 5 },
33 {"Release", 6 },
34 {"WACK", 7 },
35 {"Refresh", 8 },
36 {"Refresh(altcode)", 9 },
37 {"Multi-homed Registration", 15 },
38 {0, -1 }
41 /****************************************************************************
42 * Lookup a nmb opcode name.
43 ****************************************************************************/
44 static const char *lookup_opcode_name( int opcode )
46 const struct opcode_names *op_namep;
47 int i;
49 for(i = 0; nmb_header_opcode_names[i].nmb_opcode_name != 0; i++) {
50 op_namep = &nmb_header_opcode_names[i];
51 if(opcode == op_namep->opcode)
52 return op_namep->nmb_opcode_name;
54 return "<unknown opcode>";
57 /****************************************************************************
58 print out a res_rec structure
59 ****************************************************************************/
60 static void debug_nmb_res_rec(struct res_rec *res, const char *hdr)
62 int i, j;
64 DEBUGADD( 4, ( " %s: nmb_name=%s rr_type=%d rr_class=%d ttl=%d\n",
65 hdr,
66 nmb_namestr(&res->rr_name),
67 res->rr_type,
68 res->rr_class,
69 res->ttl ) );
71 if( res->rdlength == 0 || res->rdata == NULL )
72 return;
74 for (i = 0; i < res->rdlength; i+= 16)
76 DEBUGADD(4, (" %s %3x char ", hdr, i));
78 for (j = 0; j < 16; j++)
80 uchar x = res->rdata[i+j];
81 if (x < 32 || x > 127) x = '.';
83 if (i+j >= res->rdlength) break;
84 DEBUGADD(4, ("%c", x));
87 DEBUGADD(4, (" hex "));
89 for (j = 0; j < 16; j++)
91 if (i+j >= res->rdlength) break;
92 DEBUGADD(4, ("%02X", (uchar)res->rdata[i+j]));
95 DEBUGADD(4, ("\n"));
99 /****************************************************************************
100 process a nmb packet
101 ****************************************************************************/
102 void debug_nmb_packet(struct packet_struct *p)
104 struct nmb_packet *nmb = &p->packet.nmb;
106 if( DEBUGLVL( 4 ) )
108 dbgtext( "nmb packet from %s(%d) header: id=%d opcode=%s(%d) response=%s\n",
109 inet_ntoa(p->ip), p->port,
110 nmb->header.name_trn_id,
111 lookup_opcode_name(nmb->header.opcode),
112 nmb->header.opcode,
113 BOOLSTR(nmb->header.response) );
114 dbgtext( " header: flags: bcast=%s rec_avail=%s rec_des=%s trunc=%s auth=%s\n",
115 BOOLSTR(nmb->header.nm_flags.bcast),
116 BOOLSTR(nmb->header.nm_flags.recursion_available),
117 BOOLSTR(nmb->header.nm_flags.recursion_desired),
118 BOOLSTR(nmb->header.nm_flags.trunc),
119 BOOLSTR(nmb->header.nm_flags.authoritative) );
120 dbgtext( " header: rcode=%d qdcount=%d ancount=%d nscount=%d arcount=%d\n",
121 nmb->header.rcode,
122 nmb->header.qdcount,
123 nmb->header.ancount,
124 nmb->header.nscount,
125 nmb->header.arcount );
128 if (nmb->header.qdcount)
130 DEBUGADD( 4, ( " question: q_name=%s q_type=%d q_class=%d\n",
131 nmb_namestr(&nmb->question.question_name),
132 nmb->question.question_type,
133 nmb->question.question_class) );
136 if (nmb->answers && nmb->header.ancount)
138 debug_nmb_res_rec(nmb->answers,"answers");
140 if (nmb->nsrecs && nmb->header.nscount)
142 debug_nmb_res_rec(nmb->nsrecs,"nsrecs");
144 if (nmb->additional && nmb->header.arcount)
146 debug_nmb_res_rec(nmb->additional,"additional");
150 /*******************************************************************
151 handle "compressed" name pointers
152 ******************************************************************/
153 static BOOL handle_name_ptrs(uchar *ubuf,int *offset,int length,
154 BOOL *got_pointer,int *ret)
156 int loop_count=0;
158 while ((ubuf[*offset] & 0xC0) == 0xC0) {
159 if (!*got_pointer) (*ret) += 2;
160 (*got_pointer)=True;
161 (*offset) = ((ubuf[*offset] & ~0xC0)<<8) | ubuf[(*offset)+1];
162 if (loop_count++ == 10 || (*offset) < 0 || (*offset)>(length-2)) {
163 return(False);
166 return(True);
169 /*******************************************************************
170 parse a nmb name from "compressed" format to something readable
171 return the space taken by the name, or 0 if the name is invalid
172 ******************************************************************/
173 static int parse_nmb_name(char *inbuf,int ofs,int length, struct nmb_name *name)
175 int m,n=0;
176 uchar *ubuf = (uchar *)inbuf;
177 int ret = 0;
178 BOOL got_pointer=False;
179 int loop_count=0;
180 int offset = ofs;
182 if (length - offset < 2)
183 return(0);
185 /* handle initial name pointers */
186 if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret))
187 return(0);
189 m = ubuf[offset];
191 if (!m)
192 return(0);
193 if ((m & 0xC0) || offset+m+2 > length)
194 return(0);
196 memset((char *)name,'\0',sizeof(*name));
198 /* the "compressed" part */
199 if (!got_pointer)
200 ret += m + 2;
201 offset++;
202 while (m > 0) {
203 uchar c1,c2;
204 c1 = ubuf[offset++]-'A';
205 c2 = ubuf[offset++]-'A';
206 if ((c1 & 0xF0) || (c2 & 0xF0) || (n > sizeof(name->name)-1))
207 return(0);
208 name->name[n++] = (c1<<4) | c2;
209 m -= 2;
211 name->name[n] = 0;
213 if (n==16) {
214 /* parse out the name type,
215 its always in the 16th byte of the name */
216 name->name_type = ((uchar)name->name[15]) & 0xff;
218 /* remove trailing spaces */
219 name->name[15] = 0;
220 n = 14;
221 while (n && name->name[n]==' ')
222 name->name[n--] = 0;
225 /* now the domain parts (if any) */
226 n = 0;
227 while (ubuf[offset]) {
228 /* we can have pointers within the domain part as well */
229 if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret))
230 return(0);
232 m = ubuf[offset];
234 * Don't allow null domain parts.
236 if (!m)
237 return(0);
238 if (!got_pointer)
239 ret += m+1;
240 if (n)
241 name->scope[n++] = '.';
242 if (m+2+offset>length || n+m+1>sizeof(name->scope))
243 return(0);
244 offset++;
245 while (m--)
246 name->scope[n++] = (char)ubuf[offset++];
249 * Watch for malicious loops.
251 if (loop_count++ == 10)
252 return 0;
254 name->scope[n++] = 0;
256 return(ret);
260 /*******************************************************************
261 put a compressed nmb name into a buffer. return the length of the
262 compressed name
264 compressed names are really weird. The "compression" doubles the
265 size. The idea is that it also means that compressed names conform
266 to the doman name system. See RFC1002.
267 ******************************************************************/
268 static int put_nmb_name(char *buf,int offset,struct nmb_name *name)
270 int ret,m;
271 fstring buf1;
272 char *p;
274 if (strcmp(name->name,"*") == 0) {
275 /* special case for wildcard name */
276 memset(buf1,'\0',20);
277 buf1[0] = '*';
278 buf1[15] = name->name_type;
279 } else {
280 slprintf(buf1, sizeof(buf1) - 1,"%-15.15s%c",name->name,name->name_type);
283 buf[offset] = 0x20;
285 ret = 34;
287 for (m=0;m<16;m++) {
288 buf[offset+1+2*m] = 'A' + ((buf1[m]>>4)&0xF);
289 buf[offset+2+2*m] = 'A' + (buf1[m]&0xF);
291 offset += 33;
293 buf[offset] = 0;
295 if (name->scope[0]) {
296 /* XXXX this scope handling needs testing */
297 ret += strlen(name->scope) + 1;
298 safe_strcpy(&buf[offset+1],name->scope,sizeof(name->scope));
300 p = &buf[offset+1];
301 while ((p = strchr_m(p,'.'))) {
302 buf[offset] = PTR_DIFF(p,&buf[offset+1]);
303 offset += (buf[offset] + 1);
304 p = &buf[offset+1];
306 buf[offset] = strlen(&buf[offset+1]);
309 return(ret);
312 /*******************************************************************
313 Useful for debugging messages.
314 ******************************************************************/
316 char *nmb_namestr(struct nmb_name *n)
318 static int i=0;
319 static fstring ret[4];
320 fstring name;
321 char *p = ret[i];
323 pull_ascii_fstring(name, n->name);
324 if (!n->scope[0])
325 slprintf(p,sizeof(fstring)-1, "%s<%02x>",name,n->name_type);
326 else
327 slprintf(p,sizeof(fstring)-1, "%s<%02x>.%s",name,n->name_type,n->scope);
329 i = (i+1)%4;
330 return(p);
333 /*******************************************************************
334 allocate and parse some resource records
335 ******************************************************************/
336 static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length,
337 struct res_rec **recs, int count)
339 int i;
340 *recs = (struct res_rec *)malloc(sizeof(**recs)*count);
341 if (!*recs) return(False);
343 memset((char *)*recs,'\0',sizeof(**recs)*count);
345 for (i=0;i<count;i++) {
346 int l = parse_nmb_name(inbuf,*offset,length,&(*recs)[i].rr_name);
347 (*offset) += l;
348 if (!l || (*offset)+10 > length) {
349 SAFE_FREE(*recs);
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 SAFE_FREE(*recs);
360 return(False);
362 memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength);
363 (*offset) += (*recs)[i].rdlength;
365 return(True);
368 /*******************************************************************
369 put a resource record into a packet
370 ******************************************************************/
371 static int put_res_rec(char *buf,int offset,struct res_rec *recs,int count)
373 int ret=0;
374 int i;
376 for (i=0;i<count;i++) {
377 int l = put_nmb_name(buf,offset,&recs[i].rr_name);
378 offset += l;
379 ret += l;
380 RSSVAL(buf,offset,recs[i].rr_type);
381 RSSVAL(buf,offset+2,recs[i].rr_class);
382 RSIVAL(buf,offset+4,recs[i].ttl);
383 RSSVAL(buf,offset+8,recs[i].rdlength);
384 memcpy(buf+offset+10,recs[i].rdata,recs[i].rdlength);
385 offset += 10+recs[i].rdlength;
386 ret += 10+recs[i].rdlength;
389 return(ret);
392 /*******************************************************************
393 put a compressed name pointer record into a packet
394 ******************************************************************/
395 static int put_compressed_name_ptr(uchar *buf,int offset,struct res_rec *rec,int ptr_offset)
397 int ret=0;
398 buf[offset] = (0xC0 | ((ptr_offset >> 8) & 0xFF));
399 buf[offset+1] = (ptr_offset & 0xFF);
400 offset += 2;
401 ret += 2;
402 RSSVAL(buf,offset,rec->rr_type);
403 RSSVAL(buf,offset+2,rec->rr_class);
404 RSIVAL(buf,offset+4,rec->ttl);
405 RSSVAL(buf,offset+8,rec->rdlength);
406 memcpy(buf+offset+10,rec->rdata,rec->rdlength);
407 offset += 10+rec->rdlength;
408 ret += 10+rec->rdlength;
410 return(ret);
413 /*******************************************************************
414 parse a dgram packet. Return False if the packet can't be parsed
415 or is invalid for some reason, True otherwise
417 this is documented in section 4.4.1 of RFC1002
418 ******************************************************************/
419 static BOOL parse_dgram(char *inbuf,int length,struct dgram_packet *dgram)
421 int offset;
422 int flags;
424 memset((char *)dgram,'\0',sizeof(*dgram));
426 if (length < 14) return(False);
428 dgram->header.msg_type = CVAL(inbuf,0);
429 flags = CVAL(inbuf,1);
430 dgram->header.flags.node_type = (enum node_type)((flags>>2)&3);
431 if (flags & 1) dgram->header.flags.more = True;
432 if (flags & 2) dgram->header.flags.first = True;
433 dgram->header.dgm_id = RSVAL(inbuf,2);
434 putip((char *)&dgram->header.source_ip,inbuf+4);
435 dgram->header.source_port = RSVAL(inbuf,8);
436 dgram->header.dgm_length = RSVAL(inbuf,10);
437 dgram->header.packet_offset = RSVAL(inbuf,12);
439 offset = 14;
441 if (dgram->header.msg_type == 0x10 ||
442 dgram->header.msg_type == 0x11 ||
443 dgram->header.msg_type == 0x12) {
444 offset += parse_nmb_name(inbuf,offset,length,&dgram->source_name);
445 offset += parse_nmb_name(inbuf,offset,length,&dgram->dest_name);
448 if (offset >= length || (length-offset > sizeof(dgram->data)))
449 return(False);
451 dgram->datasize = length-offset;
452 memcpy(dgram->data,inbuf+offset,dgram->datasize);
454 return(True);
458 /*******************************************************************
459 parse a nmb packet. Return False if the packet can't be parsed
460 or is invalid for some reason, True otherwise
461 ******************************************************************/
462 static BOOL parse_nmb(char *inbuf,int length,struct nmb_packet *nmb)
464 int nm_flags,offset;
466 memset((char *)nmb,'\0',sizeof(*nmb));
468 if (length < 12) return(False);
470 /* parse the header */
471 nmb->header.name_trn_id = RSVAL(inbuf,0);
473 DEBUG(10,("parse_nmb: packet id = %d\n", nmb->header.name_trn_id));
475 nmb->header.opcode = (CVAL(inbuf,2) >> 3) & 0xF;
476 nmb->header.response = ((CVAL(inbuf,2)>>7)&1)?True:False;
477 nm_flags = ((CVAL(inbuf,2) & 0x7) << 4) + (CVAL(inbuf,3)>>4);
478 nmb->header.nm_flags.bcast = (nm_flags&1)?True:False;
479 nmb->header.nm_flags.recursion_available = (nm_flags&8)?True:False;
480 nmb->header.nm_flags.recursion_desired = (nm_flags&0x10)?True:False;
481 nmb->header.nm_flags.trunc = (nm_flags&0x20)?True:False;
482 nmb->header.nm_flags.authoritative = (nm_flags&0x40)?True:False;
483 nmb->header.rcode = CVAL(inbuf,3) & 0xF;
484 nmb->header.qdcount = RSVAL(inbuf,4);
485 nmb->header.ancount = RSVAL(inbuf,6);
486 nmb->header.nscount = RSVAL(inbuf,8);
487 nmb->header.arcount = RSVAL(inbuf,10);
489 if (nmb->header.qdcount) {
490 offset = parse_nmb_name(inbuf,12,length,&nmb->question.question_name);
491 if (!offset) return(False);
493 if (length - (12+offset) < 4) return(False);
494 nmb->question.question_type = RSVAL(inbuf,12+offset);
495 nmb->question.question_class = RSVAL(inbuf,12+offset+2);
497 offset += 12+4;
498 } else {
499 offset = 12;
502 /* and any resource records */
503 if (nmb->header.ancount &&
504 !parse_alloc_res_rec(inbuf,&offset,length,&nmb->answers,
505 nmb->header.ancount))
506 return(False);
508 if (nmb->header.nscount &&
509 !parse_alloc_res_rec(inbuf,&offset,length,&nmb->nsrecs,
510 nmb->header.nscount))
511 return(False);
513 if (nmb->header.arcount &&
514 !parse_alloc_res_rec(inbuf,&offset,length,&nmb->additional,
515 nmb->header.arcount))
516 return(False);
518 return(True);
521 /*******************************************************************
522 'Copy constructor' for an nmb packet
523 ******************************************************************/
524 static struct packet_struct *copy_nmb_packet(struct packet_struct *packet)
526 struct nmb_packet *nmb;
527 struct nmb_packet *copy_nmb;
528 struct packet_struct *pkt_copy;
530 if(( pkt_copy = (struct packet_struct *)malloc(sizeof(*packet))) == NULL)
532 DEBUG(0,("copy_nmb_packet: malloc fail.\n"));
533 return NULL;
536 /* Structure copy of entire thing. */
538 *pkt_copy = *packet;
540 /* Ensure this copy is not locked. */
541 pkt_copy->locked = False;
543 /* Ensure this copy has no resource records. */
544 nmb = &packet->packet.nmb;
545 copy_nmb = &pkt_copy->packet.nmb;
547 copy_nmb->answers = NULL;
548 copy_nmb->nsrecs = NULL;
549 copy_nmb->additional = NULL;
551 /* Now copy any resource records. */
553 if (nmb->answers)
555 if((copy_nmb->answers = (struct res_rec *)
556 malloc(nmb->header.ancount * sizeof(struct res_rec))) == NULL)
557 goto free_and_exit;
558 memcpy((char *)copy_nmb->answers, (char *)nmb->answers,
559 nmb->header.ancount * sizeof(struct res_rec));
561 if (nmb->nsrecs)
563 if((copy_nmb->nsrecs = (struct res_rec *)
564 malloc(nmb->header.nscount * sizeof(struct res_rec))) == NULL)
565 goto free_and_exit;
566 memcpy((char *)copy_nmb->nsrecs, (char *)nmb->nsrecs,
567 nmb->header.nscount * sizeof(struct res_rec));
569 if (nmb->additional)
571 if((copy_nmb->additional = (struct res_rec *)
572 malloc(nmb->header.arcount * sizeof(struct res_rec))) == NULL)
573 goto free_and_exit;
574 memcpy((char *)copy_nmb->additional, (char *)nmb->additional,
575 nmb->header.arcount * sizeof(struct res_rec));
578 return pkt_copy;
580 free_and_exit:
582 SAFE_FREE(copy_nmb->answers);
583 SAFE_FREE(copy_nmb->nsrecs);
584 SAFE_FREE(copy_nmb->additional);
585 SAFE_FREE(pkt_copy);
587 DEBUG(0,("copy_nmb_packet: malloc fail in resource records.\n"));
588 return NULL;
591 /*******************************************************************
592 'Copy constructor' for a dgram packet
593 ******************************************************************/
594 static struct packet_struct *copy_dgram_packet(struct packet_struct *packet)
596 struct packet_struct *pkt_copy;
598 if(( pkt_copy = (struct packet_struct *)malloc(sizeof(*packet))) == NULL)
600 DEBUG(0,("copy_dgram_packet: malloc fail.\n"));
601 return NULL;
604 /* Structure copy of entire thing. */
606 *pkt_copy = *packet;
608 /* Ensure this copy is not locked. */
609 pkt_copy->locked = False;
611 /* There are no additional pointers in a dgram packet,
612 we are finished. */
613 return pkt_copy;
616 /*******************************************************************
617 'Copy constructor' for a generic packet
618 ******************************************************************/
619 struct packet_struct *copy_packet(struct packet_struct *packet)
621 if(packet->packet_type == NMB_PACKET)
622 return copy_nmb_packet(packet);
623 else if (packet->packet_type == DGRAM_PACKET)
624 return copy_dgram_packet(packet);
625 return NULL;
628 /*******************************************************************
629 free up any resources associated with an nmb packet
630 ******************************************************************/
631 static void free_nmb_packet(struct nmb_packet *nmb)
633 SAFE_FREE(nmb->answers);
634 SAFE_FREE(nmb->nsrecs);
635 SAFE_FREE(nmb->additional);
638 /*******************************************************************
639 free up any resources associated with a dgram packet
640 ******************************************************************/
641 static void free_dgram_packet(struct dgram_packet *nmb)
643 /* We have nothing to do for a dgram packet. */
646 /*******************************************************************
647 free up any resources associated with a packet
648 ******************************************************************/
649 void free_packet(struct packet_struct *packet)
651 if (packet->locked)
652 return;
653 if (packet->packet_type == NMB_PACKET)
654 free_nmb_packet(&packet->packet.nmb);
655 else if (packet->packet_type == DGRAM_PACKET)
656 free_dgram_packet(&packet->packet.dgram);
657 ZERO_STRUCTPN(packet);
658 SAFE_FREE(packet);
661 /*******************************************************************
662 parse a packet buffer into a packet structure
663 ******************************************************************/
664 struct packet_struct *parse_packet(char *buf,int length,
665 enum packet_type packet_type)
667 extern struct in_addr lastip;
668 extern int lastport;
669 struct packet_struct *p;
670 BOOL ok=False;
672 p = (struct packet_struct *)malloc(sizeof(*p));
673 if (!p) return(NULL);
675 p->next = NULL;
676 p->prev = NULL;
677 p->ip = lastip;
678 p->port = lastport;
679 p->locked = False;
680 p->timestamp = time(NULL);
681 p->packet_type = packet_type;
683 switch (packet_type) {
684 case NMB_PACKET:
685 ok = parse_nmb(buf,length,&p->packet.nmb);
686 break;
688 case DGRAM_PACKET:
689 ok = parse_dgram(buf,length,&p->packet.dgram);
690 break;
693 if (!ok) {
694 free_packet(p);
695 return NULL;
698 return p;
701 /*******************************************************************
702 read a packet from a socket and parse it, returning a packet ready
703 to be used or put on the queue. This assumes a UDP socket
704 ******************************************************************/
705 struct packet_struct *read_packet(int fd,enum packet_type packet_type)
707 struct packet_struct *packet;
708 char buf[MAX_DGRAM_SIZE];
709 int length;
711 length = read_udp_socket(fd,buf,sizeof(buf));
712 if (length < MIN_DGRAM_SIZE) return(NULL);
714 packet = parse_packet(buf, length, packet_type);
715 if (!packet) return NULL;
717 packet->fd = fd;
719 num_good_receives++;
721 DEBUG(5,("Received a packet of len %d from (%s) port %d\n",
722 length, inet_ntoa(packet->ip), packet->port ) );
724 return(packet);
728 /*******************************************************************
729 send a udp packet on a already open socket
730 ******************************************************************/
731 static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port)
733 BOOL ret = False;
734 int i;
735 struct sockaddr_in sock_out;
737 /* set the address and port */
738 memset((char *)&sock_out,'\0',sizeof(sock_out));
739 putip((char *)&sock_out.sin_addr,(char *)&ip);
740 sock_out.sin_port = htons( port );
741 sock_out.sin_family = AF_INET;
743 DEBUG( 5, ( "Sending a packet of len %d to (%s) on port %d\n",
744 len, inet_ntoa(ip), port ) );
747 * Patch to fix asynch error notifications from Linux kernel.
750 for (i = 0; i < 5; i++) {
751 ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out, sizeof(sock_out)) >= 0);
752 if (ret || errno != ECONNREFUSED)
753 break;
756 if (!ret)
757 DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n",
758 inet_ntoa(ip),port,strerror(errno)));
760 if (ret)
761 num_good_sends++;
763 return(ret);
766 /*******************************************************************
767 build a dgram packet ready for sending
769 XXXX This currently doesn't handle packets too big for one
770 datagram. It should split them and use the packet_offset, more and
771 first flags to handle the fragmentation. Yuck.
773 [...but it isn't clear that we would ever need to send a
774 a fragmented NBT Datagram. The IP layer does its own
775 fragmentation to ensure that messages can fit into the path
776 MTU. It *is* important to be able to receive and rebuild
777 fragmented NBT datagrams, just in case someone out there
778 really has implemented this 'feature'. crh -)------ ]
780 ******************************************************************/
781 static int build_dgram(char *buf,struct packet_struct *p)
783 struct dgram_packet *dgram = &p->packet.dgram;
784 uchar *ubuf = (uchar *)buf;
785 int offset=0;
787 /* put in the header */
788 ubuf[0] = dgram->header.msg_type;
789 ubuf[1] = (((int)dgram->header.flags.node_type)<<2);
790 if (dgram->header.flags.more) ubuf[1] |= 1;
791 if (dgram->header.flags.first) ubuf[1] |= 2;
792 RSSVAL(ubuf,2,dgram->header.dgm_id);
793 putip(ubuf+4,(char *)&dgram->header.source_ip);
794 RSSVAL(ubuf,8,dgram->header.source_port);
795 RSSVAL(ubuf,12,dgram->header.packet_offset);
797 offset = 14;
799 if (dgram->header.msg_type == 0x10 ||
800 dgram->header.msg_type == 0x11 ||
801 dgram->header.msg_type == 0x12) {
802 offset += put_nmb_name((char *)ubuf,offset,&dgram->source_name);
803 offset += put_nmb_name((char *)ubuf,offset,&dgram->dest_name);
806 memcpy(ubuf+offset,dgram->data,dgram->datasize);
807 offset += dgram->datasize;
809 /* automatically set the dgm_length
810 * NOTE: RFC1002 says the dgm_length does *not*
811 * include the fourteen-byte header. crh
813 dgram->header.dgm_length = (offset - 14);
814 RSSVAL(ubuf,10,dgram->header.dgm_length);
816 return(offset);
819 /*******************************************************************
820 Build a nmb name
821 *******************************************************************/
823 void make_nmb_name( struct nmb_name *n, const char *name, int type)
825 memset( (char *)n, '\0', sizeof(struct nmb_name) );
826 push_ascii(n->name, name, sizeof(n->name), STR_TERMINATE|STR_UPPER);
827 n->name_type = (unsigned int)type & 0xFF;
828 push_ascii(n->scope, global_scope(), 64, STR_TERMINATE);
831 /*******************************************************************
832 Compare two nmb names
833 ******************************************************************/
835 BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2)
837 return ((n1->name_type == n2->name_type) &&
838 strequal(n1->name ,n2->name ) &&
839 strequal(n1->scope,n2->scope));
842 /*******************************************************************
843 build a nmb packet ready for sending
845 XXXX this currently relies on not being passed something that expands
846 to a packet too big for the buffer. Eventually this should be
847 changed to set the trunc bit so the receiver can request the rest
848 via tcp (when that becomes supported)
849 ******************************************************************/
850 static int build_nmb(char *buf,struct packet_struct *p)
852 struct nmb_packet *nmb = &p->packet.nmb;
853 uchar *ubuf = (uchar *)buf;
854 int offset=0;
856 /* put in the header */
857 RSSVAL(ubuf,offset,nmb->header.name_trn_id);
858 ubuf[offset+2] = (nmb->header.opcode & 0xF) << 3;
859 if (nmb->header.response) ubuf[offset+2] |= (1<<7);
860 if (nmb->header.nm_flags.authoritative &&
861 nmb->header.response) ubuf[offset+2] |= 0x4;
862 if (nmb->header.nm_flags.trunc) ubuf[offset+2] |= 0x2;
863 if (nmb->header.nm_flags.recursion_desired) ubuf[offset+2] |= 0x1;
864 if (nmb->header.nm_flags.recursion_available &&
865 nmb->header.response) ubuf[offset+3] |= 0x80;
866 if (nmb->header.nm_flags.bcast) ubuf[offset+3] |= 0x10;
867 ubuf[offset+3] |= (nmb->header.rcode & 0xF);
869 RSSVAL(ubuf,offset+4,nmb->header.qdcount);
870 RSSVAL(ubuf,offset+6,nmb->header.ancount);
871 RSSVAL(ubuf,offset+8,nmb->header.nscount);
872 RSSVAL(ubuf,offset+10,nmb->header.arcount);
874 offset += 12;
875 if (nmb->header.qdcount) {
876 /* XXXX this doesn't handle a qdcount of > 1 */
877 offset += put_nmb_name((char *)ubuf,offset,&nmb->question.question_name);
878 RSSVAL(ubuf,offset,nmb->question.question_type);
879 RSSVAL(ubuf,offset+2,nmb->question.question_class);
880 offset += 4;
883 if (nmb->header.ancount)
884 offset += put_res_rec((char *)ubuf,offset,nmb->answers,
885 nmb->header.ancount);
887 if (nmb->header.nscount)
888 offset += put_res_rec((char *)ubuf,offset,nmb->nsrecs,
889 nmb->header.nscount);
892 * The spec says we must put compressed name pointers
893 * in the following outgoing packets :
894 * NAME_REGISTRATION_REQUEST, NAME_REFRESH_REQUEST,
895 * NAME_RELEASE_REQUEST.
898 if((nmb->header.response == False) &&
899 ((nmb->header.opcode == NMB_NAME_REG_OPCODE) ||
900 (nmb->header.opcode == NMB_NAME_RELEASE_OPCODE) ||
901 (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_8) ||
902 (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_9) ||
903 (nmb->header.opcode == NMB_NAME_MULTIHOMED_REG_OPCODE)) &&
904 (nmb->header.arcount == 1)) {
906 offset += put_compressed_name_ptr(ubuf,offset,nmb->additional,12);
908 } else if (nmb->header.arcount) {
909 offset += put_res_rec((char *)ubuf,offset,nmb->additional,
910 nmb->header.arcount);
912 return(offset);
916 /*******************************************************************
917 linearise a packet
918 ******************************************************************/
919 int build_packet(char *buf, struct packet_struct *p)
921 int len = 0;
923 switch (p->packet_type) {
924 case NMB_PACKET:
925 len = build_nmb(buf,p);
926 break;
928 case DGRAM_PACKET:
929 len = build_dgram(buf,p);
930 break;
933 return len;
936 /*******************************************************************
937 send a packet_struct
938 ******************************************************************/
939 BOOL send_packet(struct packet_struct *p)
941 char buf[1024];
942 int len=0;
944 memset(buf,'\0',sizeof(buf));
946 len = build_packet(buf, p);
948 if (!len) return(False);
950 return(send_udp(p->fd,buf,len,p->ip,p->port));
953 /****************************************************************************
954 receive a packet with timeout on a open UDP filedescriptor
955 The timeout is in milliseconds
956 ***************************************************************************/
957 struct packet_struct *receive_packet(int fd,enum packet_type type,int t)
959 fd_set fds;
960 struct timeval timeout;
961 int ret;
963 FD_ZERO(&fds);
964 FD_SET(fd,&fds);
965 timeout.tv_sec = t/1000;
966 timeout.tv_usec = 1000*(t%1000);
968 if ((ret = sys_select_intr(fd+1,&fds,NULL,NULL,&timeout)) == -1) {
969 /* errno should be EBADF or EINVAL. */
970 DEBUG(0,("select returned -1, errno = %s (%d)\n", strerror(errno), errno));
971 return NULL;
974 if (ret == 0) /* timeout */
975 return NULL;
977 if (FD_ISSET(fd,&fds))
978 return(read_packet(fd,type));
980 return(NULL);
984 /****************************************************************************
985 receive a UDP/137 packet either via UDP or from the unexpected packet
986 queue. The packet must be a reply packet and have the specified trn_id
987 The timeout is in milliseconds
988 ***************************************************************************/
989 struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id)
991 struct packet_struct *p;
993 p = receive_packet(fd, NMB_PACKET, t);
995 if (p && p->packet.nmb.header.response &&
996 p->packet.nmb.header.name_trn_id == trn_id) {
997 return p;
999 if (p) free_packet(p);
1001 /* try the unexpected packet queue */
1002 return receive_unexpected(NMB_PACKET, trn_id, NULL);
1005 /****************************************************************************
1006 receive a UDP/138 packet either via UDP or from the unexpected packet
1007 queue. The packet must be a reply packet and have the specified mailslot name
1008 The timeout is in milliseconds
1009 ***************************************************************************/
1010 struct packet_struct *receive_dgram_packet(int fd, int t, const char *mailslot_name)
1012 struct packet_struct *p;
1014 p = receive_packet(fd, DGRAM_PACKET, t);
1016 if (p && match_mailslot_name(p, mailslot_name)) {
1017 return p;
1019 if (p) free_packet(p);
1021 /* try the unexpected packet queue */
1022 return receive_unexpected(DGRAM_PACKET, 0, mailslot_name);
1026 /****************************************************************************
1027 see if a datagram has the right mailslot name
1028 ***************************************************************************/
1029 BOOL match_mailslot_name(struct packet_struct *p, const char *mailslot_name)
1031 struct dgram_packet *dgram = &p->packet.dgram;
1032 char *buf;
1034 buf = &dgram->data[0];
1035 buf -= 4;
1037 buf = smb_buf(buf);
1039 if (memcmp(buf, mailslot_name, strlen(mailslot_name)+1) == 0) {
1040 return True;
1043 return False;
1047 /****************************************************************************
1048 return the number of bits that match between two 4 character buffers
1049 ***************************************************************************/
1050 int matching_quad_bits(uchar *p1, uchar *p2)
1052 int i, j, ret = 0;
1053 for (i=0; i<4; i++) {
1054 if (p1[i] != p2[i]) break;
1055 ret += 8;
1058 if (i==4) return ret;
1060 for (j=0; j<8; j++) {
1061 if ((p1[i] & (1<<(7-j))) != (p2[i] & (1<<(7-j)))) break;
1062 ret++;
1065 return ret;
1069 static uchar sort_ip[4];
1071 /****************************************************************************
1072 compare two query reply records
1073 ***************************************************************************/
1074 static int name_query_comp(uchar *p1, uchar *p2)
1076 return matching_quad_bits(p2+2, sort_ip) - matching_quad_bits(p1+2, sort_ip);
1079 /****************************************************************************
1080 sort a set of 6 byte name query response records so that the IPs that
1081 have the most leading bits in common with the specified address come first
1082 ***************************************************************************/
1083 void sort_query_replies(char *data, int n, struct in_addr ip)
1085 if (n <= 1) return;
1087 putip(sort_ip, (char *)&ip);
1089 qsort(data, n, 6, QSORT_CAST name_query_comp);
1093 #define TRUNCATE_NETBIOS_NAME 1
1095 /*******************************************************************
1096 convert, possibly using a stupid microsoft-ism which has destroyed
1097 the transport independence of netbios (for CIFS vendors that usually
1098 use the Win95-type methods, not for NT to NT communication, which uses
1099 DCE/RPC and therefore full-length unicode strings...) a dns name into
1100 a netbios name.
1102 the netbios name (NOT necessarily null-terminated) is truncated to 15
1103 characters.
1105 ******************************************************************/
1106 char *dns_to_netbios_name(char *dns_name)
1108 static char netbios_name[16];
1109 int i;
1110 StrnCpy(netbios_name, dns_name, 15);
1111 netbios_name[15] = 0;
1113 #ifdef TRUNCATE_NETBIOS_NAME
1114 /* ok. this is because of a stupid microsoft-ism. if the called host
1115 name contains a '.', microsoft clients expect you to truncate the
1116 netbios name up to and including the '.' this even applies, by
1117 mistake, to workgroup (domain) names, which is _really_ daft.
1119 for (i = 15; i >= 0; i--)
1121 if (netbios_name[i] == '.')
1123 netbios_name[i] = 0;
1124 break;
1127 #endif /* TRUNCATE_NETBIOS_NAME */
1129 return netbios_name;
1133 /****************************************************************************
1134 interpret the weird netbios "name" into a unix fstring. Return the name type
1135 ****************************************************************************/
1136 static int name_interpret(char *in, fstring name)
1138 int ret;
1139 int len = (*in++) / 2;
1140 fstring out_string;
1141 char *out = out_string;
1143 *out=0;
1145 if (len > 30 || len<1) return(0);
1147 while (len--)
1149 if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
1150 *out = 0;
1151 return(0);
1153 *out = ((in[0]-'A')<<4) + (in[1]-'A');
1154 in += 2;
1155 out++;
1157 ret = out[-1];
1158 out[-1] = 0;
1160 #ifdef NETBIOS_SCOPE
1161 /* Handle any scope names */
1162 while(*in)
1164 *out++ = '.'; /* Scope names are separated by periods */
1165 len = *(uchar *)in++;
1166 StrnCpy(out, in, len);
1167 out += len;
1168 *out=0;
1169 in += len;
1171 #endif
1172 pull_ascii(name, out_string, sizeof(fstring), sizeof(out_string), STR_TERMINATE);
1174 return(ret);
1177 /****************************************************************************
1178 mangle a name into netbios format
1180 Note: <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
1181 ****************************************************************************/
1182 int name_mangle( char *In, char *Out, char name_type )
1184 int i;
1185 int c;
1186 int len;
1187 char buf[20];
1188 char *p = Out;
1190 /* Safely copy the input string, In, into buf[]. */
1191 (void)memset( buf, 0, 20 );
1192 if (strcmp(In,"*") == 0)
1193 buf[0] = '*';
1194 else
1195 (void)slprintf( buf, sizeof(buf) - 1, "%-15.15s%c", In, name_type );
1197 /* Place the length of the first field into the output buffer. */
1198 p[0] = 32;
1199 p++;
1201 /* Now convert the name to the rfc1001/1002 format. */
1202 for( i = 0; i < 16; i++ )
1204 c = toupper( buf[i] );
1205 p[i*2] = ( (c >> 4) & 0x000F ) + 'A';
1206 p[(i*2)+1] = (c & 0x000F) + 'A';
1208 p += 32;
1209 p[0] = '\0';
1211 /* Add the scope string. */
1212 for( i = 0, len = 0; *(global_scope()) != '\0'; i++, len++ )
1214 switch( (global_scope())[i] )
1216 case '\0':
1217 p[0] = len;
1218 if( len > 0 )
1219 p[len+1] = 0;
1220 return( name_len(Out) );
1221 case '.':
1222 p[0] = len;
1223 p += (len + 1);
1224 len = -1;
1225 break;
1226 default:
1227 p[len+1] = (global_scope())[i];
1228 break;
1232 return( name_len(Out) );
1233 } /* name_mangle */
1236 /****************************************************************************
1237 find a pointer to a netbios name
1238 ****************************************************************************/
1239 static char *name_ptr(char *buf,int ofs)
1241 uchar c = *(uchar *)(buf+ofs);
1243 if ((c & 0xC0) == 0xC0)
1245 uint16 l = RSVAL(buf, ofs) & 0x3FFF;
1246 DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
1247 return(buf + l);
1249 else
1250 return(buf+ofs);
1253 /****************************************************************************
1254 extract a netbios name from a buf (into a unix string) return name type
1255 ****************************************************************************/
1256 int name_extract(char *buf,int ofs, fstring name)
1258 char *p = name_ptr(buf,ofs);
1259 int d = PTR_DIFF(p,buf+ofs);
1260 pstrcpy(name,"");
1261 if (d < -50 || d > 50) return(0);
1262 return(name_interpret(p,name));
1265 /****************************************************************************
1266 return the total storage length of a mangled name
1267 ****************************************************************************/
1268 int name_len(char *s1)
1270 /* NOTE: this argument _must_ be unsigned */
1271 uchar *s = (uchar *)s1;
1272 int len;
1274 /* If the two high bits of the byte are set, return 2. */
1275 if (0xC0 == (*s & 0xC0))
1276 return(2);
1278 /* Add up the length bytes. */
1279 for (len = 1; (*s); s += (*s) + 1) {
1280 len += *s + 1;
1281 SMB_ASSERT(len < 80);
1284 return(len);
1285 } /* name_len */