2 Unix SMB/Netbios implementation.
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.
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;
33 } nmb_header_opcode_names[] = {
39 {"Refresh(altcode)", 9 },
40 {"Multi-homed Registration", 15 },
44 /****************************************************************************
45 * Lookup a nmb opcode name.
46 ****************************************************************************/
47 static char *lookup_opcode_name( int opcode )
49 struct opcode_names *op_namep;
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)
67 DEBUGADD( 4, ( " %s: nmb_name=%s rr_type=%d rr_class=%d ttl=%d\n",
69 nmb_namestr(&res->rr_name),
74 if( res->rdlength == 0 || res->rdata == NULL )
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]));
102 /****************************************************************************
104 ****************************************************************************/
105 void debug_nmb_packet(struct packet_struct *p)
107 struct nmb_packet *nmb = &p->packet.nmb;
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),
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",
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)
161 while ((ubuf[*offset] & 0xC0) == 0xC0) {
162 if (!*got_pointer) (*ret) += 2;
164 (*offset) = ((ubuf[*offset] & ~0xC0)<<8) | ubuf[(*offset)+1];
165 if (loop_count++ == 10 || (*offset) < 0 || (*offset)>(length-2)) {
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)
179 uchar *ubuf = (uchar *)inbuf;
181 BOOL got_pointer=False;
184 if (length - offset < 2)
187 /* handle initial name pointers */
188 if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret))
195 if ((m & 0xC0) || offset+m+2 > length)
198 memset((char *)name,'\0',sizeof(*name));
200 /* the "compressed" part */
206 c1 = ubuf[offset++]-'A';
207 c2 = ubuf[offset++]-'A';
208 if ((c1 & 0xF0) || (c2 & 0xF0) || (n > sizeof(name->name)-1))
210 name->name[n++] = (c1<<4) | c2;
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 */
223 while (n && name->name[n]==' ')
227 /* now the domain parts (if any) */
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))
236 * Don't allow null domain parts.
243 name->scope[n++] = '.';
244 if (m+2+offset>length || n+m+1>sizeof(name->scope))
248 name->scope[n++] = (char)ubuf[offset++];
251 * Watch for malicious loops.
253 if (loop_count++ == 10)
256 name->scope[n++] = 0;
262 /*******************************************************************
263 put a compressed nmb name into a buffer. return the length of the
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)
276 if (strcmp(name->name,"*") == 0) {
277 /* special case for wildcard name */
278 memset(buf1,'\0',20);
280 buf1[15] = name->name_type;
282 slprintf(buf1, sizeof(buf1) - 1,"%-15.15s%c",name->name,name->name_type);
290 buf[offset+1+2*m] = 'A' + ((buf1[m]>>4)&0xF);
291 buf[offset+2+2*m] = 'A' + (buf1[m]&0xF);
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);
303 while ((p = strchr(p,'.'))) {
304 buf[offset] = PTR_DIFF(p,&buf[offset+1]);
305 offset += (buf[offset] + 1);
308 buf[offset] = strlen(&buf[offset+1]);
314 /*******************************************************************
315 useful for debugging messages
316 ******************************************************************/
317 char *nmb_namestr(struct nmb_name *n)
320 static fstring ret[4];
324 slprintf(p,sizeof(fstring)-1, "%s<%02x>",n->name,n->name_type);
326 slprintf(p,sizeof(fstring)-1, "%s<%02x>.%s",n->name,n->name_type,n->scope);
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)
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);
347 if (!l || (*offset)+10 > length) {
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);
357 if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) ||
358 (*offset)+(*recs)[i].rdlength > length) {
363 memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength);
364 (*offset) += (*recs)[i].rdlength;
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)
377 for (i=0;i<count;i++) {
378 int l = put_nmb_name(buf,offset,&recs[i].rr_name);
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;
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)
399 buf[offset] = (0xC0 | ((ptr_offset >> 8) & 0xFF));
400 buf[offset+1] = (ptr_offset & 0xFF);
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;
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)
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);
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)))
452 dgram->datasize = length-offset;
453 memcpy(dgram->data,inbuf+offset,dgram->datasize);
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)
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);
503 /* and any resource records */
504 if (nmb->header.ancount &&
505 !parse_alloc_res_rec(inbuf,&offset,length,&nmb->answers,
506 nmb->header.ancount))
509 if (nmb->header.nscount &&
510 !parse_alloc_res_rec(inbuf,&offset,length,&nmb->nsrecs,
511 nmb->header.nscount))
514 if (nmb->header.arcount &&
515 !parse_alloc_res_rec(inbuf,&offset,length,&nmb->additional,
516 nmb->header.arcount))
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"));
537 /* Structure copy of entire thing. */
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. */
556 if((copy_nmb->answers = (struct res_rec *)
557 malloc(nmb->header.ancount * sizeof(struct res_rec))) == NULL)
559 memcpy((char *)copy_nmb->answers, (char *)nmb->answers,
560 nmb->header.ancount * sizeof(struct res_rec));
564 if((copy_nmb->nsrecs = (struct res_rec *)
565 malloc(nmb->header.nscount * sizeof(struct res_rec))) == NULL)
567 memcpy((char *)copy_nmb->nsrecs, (char *)nmb->nsrecs,
568 nmb->header.nscount * sizeof(struct res_rec));
572 if((copy_nmb->additional = (struct res_rec *)
573 malloc(nmb->header.arcount * sizeof(struct res_rec))) == NULL)
575 memcpy((char *)copy_nmb->additional, (char *)nmb->additional,
576 nmb->header.arcount * sizeof(struct res_rec));
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"));
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"));
614 /* Structure copy of entire thing. */
618 /* Ensure this copy is not locked. */
619 pkt_copy->locked = False;
621 /* There are no additional pointers in a dgram packet,
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);
638 /*******************************************************************
639 free up any resources associated with an nmb packet
640 ******************************************************************/
641 static void free_nmb_packet(struct nmb_packet *nmb)
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)
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);
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;
688 struct packet_struct *p;
691 p = (struct packet_struct *)malloc(sizeof(*p));
692 if (!p) return(NULL);
699 p->timestamp = time(NULL);
700 p->packet_type = packet_type;
702 switch (packet_type) {
704 ok = parse_nmb(buf,length,&p->packet.nmb);
708 ok = parse_dgram(buf,length,&p->packet.dgram);
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];
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;
740 DEBUG(5,("Received a packet of len %d from (%s) port %d\n",
741 length, inet_ntoa(packet->ip), packet->port ) );
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)
753 struct sockaddr_in sock_out;
755 /* set the address and port */
756 memset((char *)&sock_out,'\0',sizeof(sock_out));
757 putip((char *)&sock_out.sin_addr,(char *)&ip);
758 sock_out.sin_port = htons( port );
759 sock_out.sin_family = AF_INET;
761 DEBUG( 5, ( "Sending a packet of len %d to (%s) on port %d\n",
762 len, inet_ntoa(ip), port ) );
764 ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out,
765 sizeof(sock_out)) >= 0);
768 DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n",
769 inet_ntoa(ip),port,strerror(errno)));
777 /*******************************************************************
778 build a dgram packet ready for sending
780 XXXX This currently doesn't handle packets too big for one
781 datagram. It should split them and use the packet_offset, more and
782 first flags to handle the fragmentation. Yuck.
783 ******************************************************************/
784 static int build_dgram(char *buf,struct packet_struct *p)
786 struct dgram_packet *dgram = &p->packet.dgram;
787 uchar *ubuf = (uchar *)buf;
790 /* put in the header */
791 ubuf[0] = dgram->header.msg_type;
792 ubuf[1] = (((int)dgram->header.flags.node_type)<<2);
793 if (dgram->header.flags.more) ubuf[1] |= 1;
794 if (dgram->header.flags.first) ubuf[1] |= 2;
795 RSSVAL(ubuf,2,dgram->header.dgm_id);
796 putip(ubuf+4,(char *)&dgram->header.source_ip);
797 RSSVAL(ubuf,8,dgram->header.source_port);
798 RSSVAL(ubuf,12,dgram->header.packet_offset);
802 if (dgram->header.msg_type == 0x10 ||
803 dgram->header.msg_type == 0x11 ||
804 dgram->header.msg_type == 0x12) {
805 offset += put_nmb_name((char *)ubuf,offset,&dgram->source_name);
806 offset += put_nmb_name((char *)ubuf,offset,&dgram->dest_name);
809 memcpy(ubuf+offset,dgram->data,dgram->datasize);
810 offset += dgram->datasize;
812 /* automatically set the dgm_length */
813 dgram->header.dgm_length = offset;
814 RSSVAL(ubuf,10,dgram->header.dgm_length);
819 /*******************************************************************
821 *******************************************************************/
822 void make_nmb_name( struct nmb_name *n, const char *name, int type)
824 extern pstring global_scope;
825 memset( (char *)n, '\0', sizeof(struct nmb_name) );
826 StrnCpy( n->name, name, 15 );
828 n->name_type = (unsigned int)type & 0xFF;
829 StrnCpy( n->scope, global_scope, 63 );
830 strupper( n->scope );
833 /*******************************************************************
834 Compare two nmb names
835 ******************************************************************/
837 BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2)
839 return ((n1->name_type == n2->name_type) &&
840 strequal(n1->name ,n2->name ) &&
841 strequal(n1->scope,n2->scope));
844 /*******************************************************************
845 build a nmb packet ready for sending
847 XXXX this currently relies on not being passed something that expands
848 to a packet too big for the buffer. Eventually this should be
849 changed to set the trunc bit so the receiver can request the rest
850 via tcp (when that becomes supported)
851 ******************************************************************/
852 static int build_nmb(char *buf,struct packet_struct *p)
854 struct nmb_packet *nmb = &p->packet.nmb;
855 uchar *ubuf = (uchar *)buf;
858 /* put in the header */
859 RSSVAL(ubuf,offset,nmb->header.name_trn_id);
860 ubuf[offset+2] = (nmb->header.opcode & 0xF) << 3;
861 if (nmb->header.response) ubuf[offset+2] |= (1<<7);
862 if (nmb->header.nm_flags.authoritative &&
863 nmb->header.response) ubuf[offset+2] |= 0x4;
864 if (nmb->header.nm_flags.trunc) ubuf[offset+2] |= 0x2;
865 if (nmb->header.nm_flags.recursion_desired) ubuf[offset+2] |= 0x1;
866 if (nmb->header.nm_flags.recursion_available &&
867 nmb->header.response) ubuf[offset+3] |= 0x80;
868 if (nmb->header.nm_flags.bcast) ubuf[offset+3] |= 0x10;
869 ubuf[offset+3] |= (nmb->header.rcode & 0xF);
871 RSSVAL(ubuf,offset+4,nmb->header.qdcount);
872 RSSVAL(ubuf,offset+6,nmb->header.ancount);
873 RSSVAL(ubuf,offset+8,nmb->header.nscount);
874 RSSVAL(ubuf,offset+10,nmb->header.arcount);
877 if (nmb->header.qdcount) {
878 /* XXXX this doesn't handle a qdcount of > 1 */
879 offset += put_nmb_name((char *)ubuf,offset,&nmb->question.question_name);
880 RSSVAL(ubuf,offset,nmb->question.question_type);
881 RSSVAL(ubuf,offset+2,nmb->question.question_class);
885 if (nmb->header.ancount)
886 offset += put_res_rec((char *)ubuf,offset,nmb->answers,
887 nmb->header.ancount);
889 if (nmb->header.nscount)
890 offset += put_res_rec((char *)ubuf,offset,nmb->nsrecs,
891 nmb->header.nscount);
894 * The spec says we must put compressed name pointers
895 * in the following outgoing packets :
896 * NAME_REGISTRATION_REQUEST, NAME_REFRESH_REQUEST,
897 * NAME_RELEASE_REQUEST.
900 if((nmb->header.response == False) &&
901 ((nmb->header.opcode == NMB_NAME_REG_OPCODE) ||
902 (nmb->header.opcode == NMB_NAME_RELEASE_OPCODE) ||
903 (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_8) ||
904 (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_9) ||
905 (nmb->header.opcode == NMB_NAME_MULTIHOMED_REG_OPCODE)) &&
906 (nmb->header.arcount == 1)) {
908 offset += put_compressed_name_ptr(ubuf,offset,nmb->additional,12);
910 } else if (nmb->header.arcount) {
911 offset += put_res_rec((char *)ubuf,offset,nmb->additional,
912 nmb->header.arcount);
918 /*******************************************************************
920 ******************************************************************/
921 int build_packet(char *buf, struct packet_struct *p)
925 switch (p->packet_type) {
927 len = build_nmb(buf,p);
931 len = build_dgram(buf,p);
938 /*******************************************************************
940 ******************************************************************/
941 BOOL send_packet(struct packet_struct *p)
946 memset(buf,'\0',sizeof(buf));
948 len = build_packet(buf, p);
950 if (!len) return(False);
952 return(send_udp(p->fd,buf,len,p->ip,p->port));
955 /****************************************************************************
956 receive a packet with timeout on a open UDP filedescriptor
957 The timeout is in milliseconds
958 ***************************************************************************/
959 struct packet_struct *receive_packet(int fd,enum packet_type type,int t)
962 struct timeval timeout;
967 timeout.tv_sec = t/1000;
968 timeout.tv_usec = 1000*(t%1000);
970 if ((ret = sys_select_intr(fd+1,&fds,&timeout)) == -1) {
971 /* errno should be EBADF or EINVAL. */
972 DEBUG(0,("select returned -1, errno = %s (%d)\n", strerror(errno), errno));
976 if (ret == 0) /* timeout */
979 if (FD_ISSET(fd,&fds))
980 return(read_packet(fd,type));
986 /****************************************************************************
987 receive a UDP/137 packet either via UDP or from the unexpected packet
988 queue. The packet must be a reply packet and have the specified trn_id
989 The timeout is in milliseconds
990 ***************************************************************************/
991 struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id)
993 struct packet_struct *p;
995 p = receive_packet(fd, NMB_PACKET, t);
997 if (p && p->packet.nmb.header.response &&
998 p->packet.nmb.header.name_trn_id == trn_id) {
1001 if (p) free_packet(p);
1003 /* try the unexpected packet queue */
1004 return receive_unexpected(NMB_PACKET, trn_id, NULL);
1007 /****************************************************************************
1008 receive a UDP/138 packet either via UDP or from the unexpected packet
1009 queue. The packet must be a reply packet and have the specified mailslot name
1010 The timeout is in milliseconds
1011 ***************************************************************************/
1012 struct packet_struct *receive_dgram_packet(int fd, int t, char *mailslot_name)
1014 struct packet_struct *p;
1016 p = receive_packet(fd, DGRAM_PACKET, t);
1018 if (p && match_mailslot_name(p, mailslot_name)) {
1021 if (p) free_packet(p);
1023 /* try the unexpected packet queue */
1024 return receive_unexpected(DGRAM_PACKET, 0, mailslot_name);
1028 /****************************************************************************
1029 see if a datagram has the right mailslot name
1030 ***************************************************************************/
1031 BOOL match_mailslot_name(struct packet_struct *p, char *mailslot_name)
1033 struct dgram_packet *dgram = &p->packet.dgram;
1036 buf = &dgram->data[0];
1041 if (memcmp(buf, mailslot_name, strlen(mailslot_name)+1) == 0) {
1049 /****************************************************************************
1050 return the number of bits that match between two 4 character buffers
1051 ***************************************************************************/
1052 static int matching_bits(uchar *p1, uchar *p2)
1055 for (i=0; i<4; i++) {
1056 if (p1[i] != p2[i]) break;
1060 if (i==4) return ret;
1062 for (j=0; j<8; j++) {
1063 if ((p1[i] & (1<<(7-j))) != (p2[i] & (1<<(7-j)))) break;
1071 static uchar sort_ip[4];
1073 /****************************************************************************
1074 compare two query reply records
1075 ***************************************************************************/
1076 static int name_query_comp(uchar *p1, uchar *p2)
1078 return matching_bits(p2+2, sort_ip) - matching_bits(p1+2, sort_ip);
1081 /****************************************************************************
1082 sort a set of 6 byte name query response records so that the IPs that
1083 have the most leading bits in common with the specified address come first
1084 ***************************************************************************/
1085 void sort_query_replies(char *data, int n, struct in_addr ip)
1089 putip(sort_ip, (char *)&ip);
1091 qsort(data, n, 6, QSORT_CAST name_query_comp);
1095 #define TRUNCATE_NETBIOS_NAME 1
1097 /*******************************************************************
1098 convert, possibly using a stupid microsoft-ism which has destroyed
1099 the transport independence of netbios (for CIFS vendors that usually
1100 use the Win95-type methods, not for NT to NT communication, which uses
1101 DCE/RPC and therefore full-length unicode strings...) a dns name into
1104 the netbios name (NOT necessarily null-terminated) is truncated to 15
1107 ******************************************************************/
1108 char *dns_to_netbios_name(char *dns_name)
1110 static char netbios_name[16];
1112 StrnCpy(netbios_name, dns_name, 15);
1113 netbios_name[15] = 0;
1115 #ifdef TRUNCATE_NETBIOS_NAME
1116 /* ok. this is because of a stupid microsoft-ism. if the called host
1117 name contains a '.', microsoft clients expect you to truncate the
1118 netbios name up to and including the '.' this even applies, by
1119 mistake, to workgroup (domain) names, which is _really_ daft.
1121 for (i = 15; i >= 0; i--)
1123 if (netbios_name[i] == '.')
1125 netbios_name[i] = 0;
1129 #endif /* TRUNCATE_NETBIOS_NAME */
1131 return netbios_name;
1135 /****************************************************************************
1136 interpret the weird netbios "name". Return the name type
1137 ****************************************************************************/
1138 static int name_interpret(char *in,char *out)
1141 int len = (*in++) / 2;
1145 if (len > 30 || len<1) return(0);
1149 if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
1153 *out = ((in[0]-'A')<<4) + (in[1]-'A');
1160 #ifdef NETBIOS_SCOPE
1161 /* Handle any scope names */
1164 *out++ = '.'; /* Scope names are separated by periods */
1165 len = *(uchar *)in++;
1166 StrnCpy(out, in, len);
1175 /****************************************************************************
1176 mangle a name into netbios format
1178 Note: <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
1179 ****************************************************************************/
1180 int name_mangle( char *In, char *Out, char name_type )
1187 extern pstring global_scope;
1189 /* Safely copy the input string, In, into buf[]. */
1190 (void)memset( buf, 0, 20 );
1191 if (strcmp(In,"*") == 0)
1194 (void)slprintf( buf, sizeof(buf) - 1, "%-15.15s%c", In, name_type );
1196 /* Place the length of the first field into the output buffer. */
1200 /* Now convert the name to the rfc1001/1002 format. */
1201 for( i = 0; i < 16; i++ )
1203 c = toupper( buf[i] );
1204 p[i*2] = ( (c >> 4) & 0x000F ) + 'A';
1205 p[(i*2)+1] = (c & 0x000F) + 'A';
1210 /* Add the scope string. */
1211 for( i = 0, len = 0; NULL != global_scope; i++, len++ )
1213 switch( global_scope[i] )
1219 return( name_len(Out) );
1226 p[len+1] = global_scope[i];
1231 return( name_len(Out) );
1235 /****************************************************************************
1236 find a pointer to a netbios name
1237 ****************************************************************************/
1238 static char *name_ptr(char *buf,int ofs)
1240 uchar c = *(uchar *)(buf+ofs);
1242 if ((c & 0xC0) == 0xC0)
1244 uint16 l = RSVAL(buf, ofs) & 0x3FFF;
1245 DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
1252 /****************************************************************************
1253 extract a netbios name from a buf
1254 ****************************************************************************/
1255 int name_extract(char *buf,int ofs,char *name)
1257 char *p = name_ptr(buf,ofs);
1258 int d = PTR_DIFF(p,buf+ofs);
1260 if (d < -50 || d > 50) return(0);
1261 return(name_interpret(p,name));
1264 /****************************************************************************
1265 return the total storage length of a mangled name
1266 ****************************************************************************/
1267 int name_len(char *s1)
1269 /* NOTE: this argument _must_ be unsigned */
1270 uchar *s = (uchar *)s1;
1273 /* If the two high bits of the byte are set, return 2. */
1274 if (0xC0 == (*s & 0xC0))
1277 /* Add up the length bytes. */
1278 for (len = 1; (*s); s += (*s) + 1) {
1280 SMB_ASSERT(len < 80);