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 int num_good_sends
= 0;
26 int num_good_receives
= 0;
28 static const struct opcode_names
{
29 char *nmb_opcode_name
;
31 } nmb_header_opcode_names
[] = {
37 {"Refresh(altcode)", 9 },
38 {"Multi-homed Registration", 15 },
42 /****************************************************************************
43 * Lookup a nmb opcode name.
44 ****************************************************************************/
45 static const char *lookup_opcode_name( int opcode
)
47 const struct opcode_names
*op_namep
;
50 for(i
= 0; nmb_header_opcode_names
[i
].nmb_opcode_name
!= 0; i
++) {
51 op_namep
= &nmb_header_opcode_names
[i
];
52 if(opcode
== op_namep
->opcode
)
53 return op_namep
->nmb_opcode_name
;
55 return "<unknown opcode>";
58 /****************************************************************************
59 print out a res_rec structure
60 ****************************************************************************/
61 static void debug_nmb_res_rec(struct res_rec
*res
, char *hdr
)
65 DEBUGADD( 4, ( " %s: nmb_name=%s rr_type=%d rr_class=%d ttl=%d\n",
67 nmb_namestr(&res
->rr_name
),
72 if( res
->rdlength
== 0 || res
->rdata
== NULL
)
75 for (i
= 0; i
< res
->rdlength
; i
+= 16)
77 DEBUGADD(4, (" %s %3x char ", hdr
, i
));
79 for (j
= 0; j
< 16; j
++)
81 uchar x
= res
->rdata
[i
+j
];
82 if (x
< 32 || x
> 127) x
= '.';
84 if (i
+j
>= res
->rdlength
) break;
85 DEBUGADD(4, ("%c", x
));
88 DEBUGADD(4, (" hex "));
90 for (j
= 0; j
< 16; j
++)
92 if (i
+j
>= res
->rdlength
) break;
93 DEBUGADD(4, ("%02X", (uchar
)res
->rdata
[i
+j
]));
100 /****************************************************************************
102 ****************************************************************************/
103 void debug_nmb_packet(struct packet_struct
*p
)
105 struct nmb_packet
*nmb
= &p
->packet
.nmb
;
109 dbgtext( "nmb packet from %s(%d) header: id=%d opcode=%s(%d) response=%s\n",
110 inet_ntoa(p
->ip
), p
->port
,
111 nmb
->header
.name_trn_id
,
112 lookup_opcode_name(nmb
->header
.opcode
),
114 BOOLSTR(nmb
->header
.response
) );
115 dbgtext( " header: flags: bcast=%s rec_avail=%s rec_des=%s trunc=%s auth=%s\n",
116 BOOLSTR(nmb
->header
.nm_flags
.bcast
),
117 BOOLSTR(nmb
->header
.nm_flags
.recursion_available
),
118 BOOLSTR(nmb
->header
.nm_flags
.recursion_desired
),
119 BOOLSTR(nmb
->header
.nm_flags
.trunc
),
120 BOOLSTR(nmb
->header
.nm_flags
.authoritative
) );
121 dbgtext( " header: rcode=%d qdcount=%d ancount=%d nscount=%d arcount=%d\n",
126 nmb
->header
.arcount
);
129 if (nmb
->header
.qdcount
)
131 DEBUGADD( 4, ( " question: q_name=%s q_type=%d q_class=%d\n",
132 nmb_namestr(&nmb
->question
.question_name
),
133 nmb
->question
.question_type
,
134 nmb
->question
.question_class
) );
137 if (nmb
->answers
&& nmb
->header
.ancount
)
139 debug_nmb_res_rec(nmb
->answers
,"answers");
141 if (nmb
->nsrecs
&& nmb
->header
.nscount
)
143 debug_nmb_res_rec(nmb
->nsrecs
,"nsrecs");
145 if (nmb
->additional
&& nmb
->header
.arcount
)
147 debug_nmb_res_rec(nmb
->additional
,"additional");
151 /*******************************************************************
152 handle "compressed" name pointers
153 ******************************************************************/
154 static BOOL
handle_name_ptrs(uchar
*ubuf
,int *offset
,int length
,
155 BOOL
*got_pointer
,int *ret
)
159 while ((ubuf
[*offset
] & 0xC0) == 0xC0) {
160 if (!*got_pointer
) (*ret
) += 2;
162 (*offset
) = ((ubuf
[*offset
] & ~0xC0)<<8) | ubuf
[(*offset
)+1];
163 if (loop_count
++ == 10 || (*offset
) < 0 || (*offset
)>(length
-2)) {
170 /*******************************************************************
171 parse a nmb name from "compressed" format to something readable
172 return the space taken by the name, or 0 if the name is invalid
173 ******************************************************************/
174 static int parse_nmb_name(char *inbuf
,int ofs
,int length
, struct nmb_name
*name
)
177 uchar
*ubuf
= (uchar
*)inbuf
;
179 BOOL got_pointer
=False
;
183 if (length
- offset
< 2)
186 /* handle initial name pointers */
187 if (!handle_name_ptrs(ubuf
,&offset
,length
,&got_pointer
,&ret
))
194 if ((m
& 0xC0) || offset
+m
+2 > length
)
197 memset((char *)name
,'\0',sizeof(*name
));
199 /* the "compressed" part */
205 c1
= ubuf
[offset
++]-'A';
206 c2
= ubuf
[offset
++]-'A';
207 if ((c1
& 0xF0) || (c2
& 0xF0) || (n
> sizeof(name
->name
)-1))
209 name
->name
[n
++] = (c1
<<4) | c2
;
215 /* parse out the name type,
216 its always in the 16th byte of the name */
217 name
->name_type
= ((uchar
)name
->name
[15]) & 0xff;
219 /* remove trailing spaces */
222 while (n
&& name
->name
[n
]==' ')
226 /* now the domain parts (if any) */
228 while (ubuf
[offset
]) {
229 /* we can have pointers within the domain part as well */
230 if (!handle_name_ptrs(ubuf
,&offset
,length
,&got_pointer
,&ret
))
235 * Don't allow null domain parts.
242 name
->scope
[n
++] = '.';
243 if (m
+2+offset
>length
|| n
+m
+1>sizeof(name
->scope
))
247 name
->scope
[n
++] = (char)ubuf
[offset
++];
250 * Watch for malicious loops.
252 if (loop_count
++ == 10)
255 name
->scope
[n
++] = 0;
261 /*******************************************************************
262 put a compressed nmb name into a buffer. return the length of the
265 compressed names are really weird. The "compression" doubles the
266 size. The idea is that it also means that compressed names conform
267 to the doman name system. See RFC1002.
268 ******************************************************************/
269 static int put_nmb_name(char *buf
,int offset
,struct nmb_name
*name
)
275 if (strcmp(name
->name
,"*") == 0) {
276 /* special case for wildcard name */
277 memset(buf1
,'\0',20);
279 buf1
[15] = name
->name_type
;
281 slprintf(buf1
, sizeof(buf1
) - 1,"%-15.15s%c",name
->name
,name
->name_type
);
289 buf
[offset
+1+2*m
] = 'A' + ((buf1
[m
]>>4)&0xF);
290 buf
[offset
+2+2*m
] = 'A' + (buf1
[m
]&0xF);
296 if (name
->scope
[0]) {
297 /* XXXX this scope handling needs testing */
298 ret
+= strlen(name
->scope
) + 1;
299 pstrcpy(&buf
[offset
+1],name
->scope
);
302 while ((p
= strchr_m(p
,'.'))) {
303 buf
[offset
] = PTR_DIFF(p
,&buf
[offset
+1]);
304 offset
+= (buf
[offset
] + 1);
307 buf
[offset
] = strlen(&buf
[offset
+1]);
313 /*******************************************************************
314 useful for debugging messages
315 ******************************************************************/
316 char *nmb_namestr(struct nmb_name
*n
)
319 static fstring ret
[4];
323 slprintf(p
,sizeof(fstring
)-1, "%s<%02x>",n
->name
,n
->name_type
);
325 slprintf(p
,sizeof(fstring
)-1, "%s<%02x>.%s",n
->name
,n
->name_type
,n
->scope
);
331 /*******************************************************************
332 allocate and parse some resource records
333 ******************************************************************/
334 static BOOL
parse_alloc_res_rec(char *inbuf
,int *offset
,int length
,
335 struct res_rec
**recs
, int count
)
338 *recs
= (struct res_rec
*)malloc(sizeof(**recs
)*count
);
339 if (!*recs
) return(False
);
341 memset((char *)*recs
,'\0',sizeof(**recs
)*count
);
343 for (i
=0;i
<count
;i
++) {
344 int l
= parse_nmb_name(inbuf
,*offset
,length
,&(*recs
)[i
].rr_name
);
346 if (!l
|| (*offset
)+10 > length
) {
350 (*recs
)[i
].rr_type
= RSVAL(inbuf
,(*offset
));
351 (*recs
)[i
].rr_class
= RSVAL(inbuf
,(*offset
)+2);
352 (*recs
)[i
].ttl
= RIVAL(inbuf
,(*offset
)+4);
353 (*recs
)[i
].rdlength
= RSVAL(inbuf
,(*offset
)+8);
355 if ((*recs
)[i
].rdlength
>sizeof((*recs
)[i
].rdata
) ||
356 (*offset
)+(*recs
)[i
].rdlength
> length
) {
360 memcpy((*recs
)[i
].rdata
,inbuf
+(*offset
),(*recs
)[i
].rdlength
);
361 (*offset
) += (*recs
)[i
].rdlength
;
366 /*******************************************************************
367 put a resource record into a packet
368 ******************************************************************/
369 static int put_res_rec(char *buf
,int offset
,struct res_rec
*recs
,int count
)
374 for (i
=0;i
<count
;i
++) {
375 int l
= put_nmb_name(buf
,offset
,&recs
[i
].rr_name
);
378 RSSVAL(buf
,offset
,recs
[i
].rr_type
);
379 RSSVAL(buf
,offset
+2,recs
[i
].rr_class
);
380 RSIVAL(buf
,offset
+4,recs
[i
].ttl
);
381 RSSVAL(buf
,offset
+8,recs
[i
].rdlength
);
382 memcpy(buf
+offset
+10,recs
[i
].rdata
,recs
[i
].rdlength
);
383 offset
+= 10+recs
[i
].rdlength
;
384 ret
+= 10+recs
[i
].rdlength
;
390 /*******************************************************************
391 put a compressed name pointer record into a packet
392 ******************************************************************/
393 static int put_compressed_name_ptr(uchar
*buf
,int offset
,struct res_rec
*rec
,int ptr_offset
)
396 buf
[offset
] = (0xC0 | ((ptr_offset
>> 8) & 0xFF));
397 buf
[offset
+1] = (ptr_offset
& 0xFF);
400 RSSVAL(buf
,offset
,rec
->rr_type
);
401 RSSVAL(buf
,offset
+2,rec
->rr_class
);
402 RSIVAL(buf
,offset
+4,rec
->ttl
);
403 RSSVAL(buf
,offset
+8,rec
->rdlength
);
404 memcpy(buf
+offset
+10,rec
->rdata
,rec
->rdlength
);
405 offset
+= 10+rec
->rdlength
;
406 ret
+= 10+rec
->rdlength
;
411 /*******************************************************************
412 parse a dgram packet. Return False if the packet can't be parsed
413 or is invalid for some reason, True otherwise
415 this is documented in section 4.4.1 of RFC1002
416 ******************************************************************/
417 static BOOL
parse_dgram(char *inbuf
,int length
,struct dgram_packet
*dgram
)
422 memset((char *)dgram
,'\0',sizeof(*dgram
));
424 if (length
< 14) return(False
);
426 dgram
->header
.msg_type
= CVAL(inbuf
,0);
427 flags
= CVAL(inbuf
,1);
428 dgram
->header
.flags
.node_type
= (enum node_type
)((flags
>>2)&3);
429 if (flags
& 1) dgram
->header
.flags
.more
= True
;
430 if (flags
& 2) dgram
->header
.flags
.first
= True
;
431 dgram
->header
.dgm_id
= RSVAL(inbuf
,2);
432 putip((char *)&dgram
->header
.source_ip
,inbuf
+4);
433 dgram
->header
.source_port
= RSVAL(inbuf
,8);
434 dgram
->header
.dgm_length
= RSVAL(inbuf
,10);
435 dgram
->header
.packet_offset
= RSVAL(inbuf
,12);
439 if (dgram
->header
.msg_type
== 0x10 ||
440 dgram
->header
.msg_type
== 0x11 ||
441 dgram
->header
.msg_type
== 0x12) {
442 offset
+= parse_nmb_name(inbuf
,offset
,length
,&dgram
->source_name
);
443 offset
+= parse_nmb_name(inbuf
,offset
,length
,&dgram
->dest_name
);
446 if (offset
>= length
|| (length
-offset
> sizeof(dgram
->data
)))
449 dgram
->datasize
= length
-offset
;
450 memcpy(dgram
->data
,inbuf
+offset
,dgram
->datasize
);
456 /*******************************************************************
457 parse a nmb packet. Return False if the packet can't be parsed
458 or is invalid for some reason, True otherwise
459 ******************************************************************/
460 static BOOL
parse_nmb(char *inbuf
,int length
,struct nmb_packet
*nmb
)
464 memset((char *)nmb
,'\0',sizeof(*nmb
));
466 if (length
< 12) return(False
);
468 /* parse the header */
469 nmb
->header
.name_trn_id
= RSVAL(inbuf
,0);
471 DEBUG(10,("parse_nmb: packet id = %d\n", nmb
->header
.name_trn_id
));
473 nmb
->header
.opcode
= (CVAL(inbuf
,2) >> 3) & 0xF;
474 nmb
->header
.response
= ((CVAL(inbuf
,2)>>7)&1)?True
:False
;
475 nm_flags
= ((CVAL(inbuf
,2) & 0x7) << 4) + (CVAL(inbuf
,3)>>4);
476 nmb
->header
.nm_flags
.bcast
= (nm_flags
&1)?True
:False
;
477 nmb
->header
.nm_flags
.recursion_available
= (nm_flags
&8)?True
:False
;
478 nmb
->header
.nm_flags
.recursion_desired
= (nm_flags
&0x10)?True
:False
;
479 nmb
->header
.nm_flags
.trunc
= (nm_flags
&0x20)?True
:False
;
480 nmb
->header
.nm_flags
.authoritative
= (nm_flags
&0x40)?True
:False
;
481 nmb
->header
.rcode
= CVAL(inbuf
,3) & 0xF;
482 nmb
->header
.qdcount
= RSVAL(inbuf
,4);
483 nmb
->header
.ancount
= RSVAL(inbuf
,6);
484 nmb
->header
.nscount
= RSVAL(inbuf
,8);
485 nmb
->header
.arcount
= RSVAL(inbuf
,10);
487 if (nmb
->header
.qdcount
) {
488 offset
= parse_nmb_name(inbuf
,12,length
,&nmb
->question
.question_name
);
489 if (!offset
) return(False
);
491 if (length
- (12+offset
) < 4) return(False
);
492 nmb
->question
.question_type
= RSVAL(inbuf
,12+offset
);
493 nmb
->question
.question_class
= RSVAL(inbuf
,12+offset
+2);
500 /* and any resource records */
501 if (nmb
->header
.ancount
&&
502 !parse_alloc_res_rec(inbuf
,&offset
,length
,&nmb
->answers
,
503 nmb
->header
.ancount
))
506 if (nmb
->header
.nscount
&&
507 !parse_alloc_res_rec(inbuf
,&offset
,length
,&nmb
->nsrecs
,
508 nmb
->header
.nscount
))
511 if (nmb
->header
.arcount
&&
512 !parse_alloc_res_rec(inbuf
,&offset
,length
,&nmb
->additional
,
513 nmb
->header
.arcount
))
519 /*******************************************************************
520 'Copy constructor' for an nmb packet
521 ******************************************************************/
522 static struct packet_struct
*copy_nmb_packet(struct packet_struct
*packet
)
524 struct nmb_packet
*nmb
;
525 struct nmb_packet
*copy_nmb
;
526 struct packet_struct
*pkt_copy
;
528 if(( pkt_copy
= (struct packet_struct
*)malloc(sizeof(*packet
))) == NULL
)
530 DEBUG(0,("copy_nmb_packet: malloc fail.\n"));
534 /* Structure copy of entire thing. */
538 /* Ensure this copy is not locked. */
539 pkt_copy
->locked
= False
;
541 /* Ensure this copy has no resource records. */
542 nmb
= &packet
->packet
.nmb
;
543 copy_nmb
= &pkt_copy
->packet
.nmb
;
545 copy_nmb
->answers
= NULL
;
546 copy_nmb
->nsrecs
= NULL
;
547 copy_nmb
->additional
= NULL
;
549 /* Now copy any resource records. */
553 if((copy_nmb
->answers
= (struct res_rec
*)
554 malloc(nmb
->header
.ancount
* sizeof(struct res_rec
))) == NULL
)
556 memcpy((char *)copy_nmb
->answers
, (char *)nmb
->answers
,
557 nmb
->header
.ancount
* sizeof(struct res_rec
));
561 if((copy_nmb
->nsrecs
= (struct res_rec
*)
562 malloc(nmb
->header
.nscount
* sizeof(struct res_rec
))) == NULL
)
564 memcpy((char *)copy_nmb
->nsrecs
, (char *)nmb
->nsrecs
,
565 nmb
->header
.nscount
* sizeof(struct res_rec
));
569 if((copy_nmb
->additional
= (struct res_rec
*)
570 malloc(nmb
->header
.arcount
* sizeof(struct res_rec
))) == NULL
)
572 memcpy((char *)copy_nmb
->additional
, (char *)nmb
->additional
,
573 nmb
->header
.arcount
* sizeof(struct res_rec
));
580 SAFE_FREE(copy_nmb
->answers
);
581 SAFE_FREE(copy_nmb
->nsrecs
);
582 SAFE_FREE(copy_nmb
->additional
);
585 DEBUG(0,("copy_nmb_packet: malloc fail in resource records.\n"));
589 /*******************************************************************
590 'Copy constructor' for a dgram packet
591 ******************************************************************/
592 static struct packet_struct
*copy_dgram_packet(struct packet_struct
*packet
)
594 struct packet_struct
*pkt_copy
;
596 if(( pkt_copy
= (struct packet_struct
*)malloc(sizeof(*packet
))) == NULL
)
598 DEBUG(0,("copy_dgram_packet: malloc fail.\n"));
602 /* Structure copy of entire thing. */
606 /* Ensure this copy is not locked. */
607 pkt_copy
->locked
= False
;
609 /* There are no additional pointers in a dgram packet,
614 /*******************************************************************
615 'Copy constructor' for a generic packet
616 ******************************************************************/
617 struct packet_struct
*copy_packet(struct packet_struct
*packet
)
619 if(packet
->packet_type
== NMB_PACKET
)
620 return copy_nmb_packet(packet
);
621 else if (packet
->packet_type
== DGRAM_PACKET
)
622 return copy_dgram_packet(packet
);
626 /*******************************************************************
627 free up any resources associated with an nmb packet
628 ******************************************************************/
629 static void free_nmb_packet(struct nmb_packet
*nmb
)
631 SAFE_FREE(nmb
->answers
);
632 SAFE_FREE(nmb
->nsrecs
);
633 SAFE_FREE(nmb
->additional
);
636 /*******************************************************************
637 free up any resources associated with a dgram packet
638 ******************************************************************/
639 static void free_dgram_packet(struct dgram_packet
*nmb
)
641 /* We have nothing to do for a dgram packet. */
644 /*******************************************************************
645 free up any resources associated with a packet
646 ******************************************************************/
647 void free_packet(struct packet_struct
*packet
)
651 if (packet
->packet_type
== NMB_PACKET
)
652 free_nmb_packet(&packet
->packet
.nmb
);
653 else if (packet
->packet_type
== DGRAM_PACKET
)
654 free_dgram_packet(&packet
->packet
.dgram
);
655 ZERO_STRUCTPN(packet
);
659 /*******************************************************************
660 parse a packet buffer into a packet structure
661 ******************************************************************/
662 struct packet_struct
*parse_packet(char *buf
,int length
,
663 enum packet_type packet_type
)
665 extern struct in_addr lastip
;
667 struct packet_struct
*p
;
670 p
= (struct packet_struct
*)malloc(sizeof(*p
));
671 if (!p
) return(NULL
);
678 p
->timestamp
= time(NULL
);
679 p
->packet_type
= packet_type
;
681 switch (packet_type
) {
683 ok
= parse_nmb(buf
,length
,&p
->packet
.nmb
);
687 ok
= parse_dgram(buf
,length
,&p
->packet
.dgram
);
699 /*******************************************************************
700 read a packet from a socket and parse it, returning a packet ready
701 to be used or put on the queue. This assumes a UDP socket
702 ******************************************************************/
703 struct packet_struct
*read_packet(int fd
,enum packet_type packet_type
)
705 struct packet_struct
*packet
;
706 char buf
[MAX_DGRAM_SIZE
];
709 length
= read_udp_socket(fd
,buf
,sizeof(buf
));
710 if (length
< MIN_DGRAM_SIZE
) return(NULL
);
712 packet
= parse_packet(buf
, length
, packet_type
);
713 if (!packet
) return NULL
;
719 DEBUG(5,("Received a packet of len %d from (%s) port %d\n",
720 length
, inet_ntoa(packet
->ip
), packet
->port
) );
726 /*******************************************************************
727 send a udp packet on a already open socket
728 ******************************************************************/
729 static BOOL
send_udp(int fd
,char *buf
,int len
,struct in_addr ip
,int port
)
733 struct sockaddr_in sock_out
;
735 /* set the address and port */
736 memset((char *)&sock_out
,'\0',sizeof(sock_out
));
737 putip((char *)&sock_out
.sin_addr
,(char *)&ip
);
738 sock_out
.sin_port
= htons( port
);
739 sock_out
.sin_family
= AF_INET
;
741 DEBUG( 5, ( "Sending a packet of len %d to (%s) on port %d\n",
742 len
, inet_ntoa(ip
), port
) );
745 * Patch to fix asynch error notifications from Linux kernel.
748 for (i
= 0; i
< 5; i
++) {
749 ret
= (sendto(fd
,buf
,len
,0,(struct sockaddr
*)&sock_out
, sizeof(sock_out
)) >= 0);
750 if (ret
|| errno
!= ECONNREFUSED
)
755 DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n",
756 inet_ntoa(ip
),port
,strerror(errno
)));
764 /*******************************************************************
765 build a dgram packet ready for sending
767 XXXX This currently doesn't handle packets too big for one
768 datagram. It should split them and use the packet_offset, more and
769 first flags to handle the fragmentation. Yuck.
770 ******************************************************************/
771 static int build_dgram(char *buf
,struct packet_struct
*p
)
773 struct dgram_packet
*dgram
= &p
->packet
.dgram
;
774 uchar
*ubuf
= (uchar
*)buf
;
777 /* put in the header */
778 ubuf
[0] = dgram
->header
.msg_type
;
779 ubuf
[1] = (((int)dgram
->header
.flags
.node_type
)<<2);
780 if (dgram
->header
.flags
.more
) ubuf
[1] |= 1;
781 if (dgram
->header
.flags
.first
) ubuf
[1] |= 2;
782 RSSVAL(ubuf
,2,dgram
->header
.dgm_id
);
783 putip(ubuf
+4,(char *)&dgram
->header
.source_ip
);
784 RSSVAL(ubuf
,8,dgram
->header
.source_port
);
785 RSSVAL(ubuf
,12,dgram
->header
.packet_offset
);
789 if (dgram
->header
.msg_type
== 0x10 ||
790 dgram
->header
.msg_type
== 0x11 ||
791 dgram
->header
.msg_type
== 0x12) {
792 offset
+= put_nmb_name((char *)ubuf
,offset
,&dgram
->source_name
);
793 offset
+= put_nmb_name((char *)ubuf
,offset
,&dgram
->dest_name
);
796 memcpy(ubuf
+offset
,dgram
->data
,dgram
->datasize
);
797 offset
+= dgram
->datasize
;
799 /* automatically set the dgm_length */
800 dgram
->header
.dgm_length
= offset
;
801 RSSVAL(ubuf
,10,dgram
->header
.dgm_length
);
806 /*******************************************************************
808 *******************************************************************/
809 void make_nmb_name( struct nmb_name
*n
, const char *name
, int type
)
811 extern pstring global_scope
;
812 memset( (char *)n
, '\0', sizeof(struct nmb_name
) );
813 push_ascii(n
->name
, name
, 16, STR_TERMINATE
|STR_UPPER
);
814 n
->name_type
= (unsigned int)type
& 0xFF;
815 StrnCpy( n
->scope
, global_scope
, 63 );
816 strupper( n
->scope
);
819 /*******************************************************************
820 Compare two nmb names
821 ******************************************************************/
823 BOOL
nmb_name_equal(struct nmb_name
*n1
, struct nmb_name
*n2
)
825 return ((n1
->name_type
== n2
->name_type
) &&
826 strequal(n1
->name
,n2
->name
) &&
827 strequal(n1
->scope
,n2
->scope
));
830 /*******************************************************************
831 build a nmb packet ready for sending
833 XXXX this currently relies on not being passed something that expands
834 to a packet too big for the buffer. Eventually this should be
835 changed to set the trunc bit so the receiver can request the rest
836 via tcp (when that becomes supported)
837 ******************************************************************/
838 static int build_nmb(char *buf
,struct packet_struct
*p
)
840 struct nmb_packet
*nmb
= &p
->packet
.nmb
;
841 uchar
*ubuf
= (uchar
*)buf
;
844 /* put in the header */
845 RSSVAL(ubuf
,offset
,nmb
->header
.name_trn_id
);
846 ubuf
[offset
+2] = (nmb
->header
.opcode
& 0xF) << 3;
847 if (nmb
->header
.response
) ubuf
[offset
+2] |= (1<<7);
848 if (nmb
->header
.nm_flags
.authoritative
&&
849 nmb
->header
.response
) ubuf
[offset
+2] |= 0x4;
850 if (nmb
->header
.nm_flags
.trunc
) ubuf
[offset
+2] |= 0x2;
851 if (nmb
->header
.nm_flags
.recursion_desired
) ubuf
[offset
+2] |= 0x1;
852 if (nmb
->header
.nm_flags
.recursion_available
&&
853 nmb
->header
.response
) ubuf
[offset
+3] |= 0x80;
854 if (nmb
->header
.nm_flags
.bcast
) ubuf
[offset
+3] |= 0x10;
855 ubuf
[offset
+3] |= (nmb
->header
.rcode
& 0xF);
857 RSSVAL(ubuf
,offset
+4,nmb
->header
.qdcount
);
858 RSSVAL(ubuf
,offset
+6,nmb
->header
.ancount
);
859 RSSVAL(ubuf
,offset
+8,nmb
->header
.nscount
);
860 RSSVAL(ubuf
,offset
+10,nmb
->header
.arcount
);
863 if (nmb
->header
.qdcount
) {
864 /* XXXX this doesn't handle a qdcount of > 1 */
865 offset
+= put_nmb_name((char *)ubuf
,offset
,&nmb
->question
.question_name
);
866 RSSVAL(ubuf
,offset
,nmb
->question
.question_type
);
867 RSSVAL(ubuf
,offset
+2,nmb
->question
.question_class
);
871 if (nmb
->header
.ancount
)
872 offset
+= put_res_rec((char *)ubuf
,offset
,nmb
->answers
,
873 nmb
->header
.ancount
);
875 if (nmb
->header
.nscount
)
876 offset
+= put_res_rec((char *)ubuf
,offset
,nmb
->nsrecs
,
877 nmb
->header
.nscount
);
880 * The spec says we must put compressed name pointers
881 * in the following outgoing packets :
882 * NAME_REGISTRATION_REQUEST, NAME_REFRESH_REQUEST,
883 * NAME_RELEASE_REQUEST.
886 if((nmb
->header
.response
== False
) &&
887 ((nmb
->header
.opcode
== NMB_NAME_REG_OPCODE
) ||
888 (nmb
->header
.opcode
== NMB_NAME_RELEASE_OPCODE
) ||
889 (nmb
->header
.opcode
== NMB_NAME_REFRESH_OPCODE_8
) ||
890 (nmb
->header
.opcode
== NMB_NAME_REFRESH_OPCODE_9
) ||
891 (nmb
->header
.opcode
== NMB_NAME_MULTIHOMED_REG_OPCODE
)) &&
892 (nmb
->header
.arcount
== 1)) {
894 offset
+= put_compressed_name_ptr(ubuf
,offset
,nmb
->additional
,12);
896 } else if (nmb
->header
.arcount
) {
897 offset
+= put_res_rec((char *)ubuf
,offset
,nmb
->additional
,
898 nmb
->header
.arcount
);
904 /*******************************************************************
906 ******************************************************************/
907 int build_packet(char *buf
, struct packet_struct
*p
)
911 switch (p
->packet_type
) {
913 len
= build_nmb(buf
,p
);
917 len
= build_dgram(buf
,p
);
924 /*******************************************************************
926 ******************************************************************/
927 BOOL
send_packet(struct packet_struct
*p
)
932 memset(buf
,'\0',sizeof(buf
));
934 len
= build_packet(buf
, p
);
936 if (!len
) return(False
);
938 return(send_udp(p
->fd
,buf
,len
,p
->ip
,p
->port
));
941 /****************************************************************************
942 receive a packet with timeout on a open UDP filedescriptor
943 The timeout is in milliseconds
944 ***************************************************************************/
945 struct packet_struct
*receive_packet(int fd
,enum packet_type type
,int t
)
948 struct timeval timeout
;
953 timeout
.tv_sec
= t
/1000;
954 timeout
.tv_usec
= 1000*(t
%1000);
956 if ((ret
= sys_select_intr(fd
+1,&fds
,&timeout
)) == -1) {
957 /* errno should be EBADF or EINVAL. */
958 DEBUG(0,("select returned -1, errno = %s (%d)\n", strerror(errno
), errno
));
962 if (ret
== 0) /* timeout */
965 if (FD_ISSET(fd
,&fds
))
966 return(read_packet(fd
,type
));
972 /****************************************************************************
973 receive a UDP/137 packet either via UDP or from the unexpected packet
974 queue. The packet must be a reply packet and have the specified trn_id
975 The timeout is in milliseconds
976 ***************************************************************************/
977 struct packet_struct
*receive_nmb_packet(int fd
, int t
, int trn_id
)
979 struct packet_struct
*p
;
981 p
= receive_packet(fd
, NMB_PACKET
, t
);
983 if (p
&& p
->packet
.nmb
.header
.response
&&
984 p
->packet
.nmb
.header
.name_trn_id
== trn_id
) {
987 if (p
) free_packet(p
);
989 /* try the unexpected packet queue */
990 return receive_unexpected(NMB_PACKET
, trn_id
, NULL
);
993 /****************************************************************************
994 receive a UDP/138 packet either via UDP or from the unexpected packet
995 queue. The packet must be a reply packet and have the specified mailslot name
996 The timeout is in milliseconds
997 ***************************************************************************/
998 struct packet_struct
*receive_dgram_packet(int fd
, int t
, char *mailslot_name
)
1000 struct packet_struct
*p
;
1002 p
= receive_packet(fd
, DGRAM_PACKET
, t
);
1004 if (p
&& match_mailslot_name(p
, mailslot_name
)) {
1007 if (p
) free_packet(p
);
1009 /* try the unexpected packet queue */
1010 return receive_unexpected(DGRAM_PACKET
, 0, mailslot_name
);
1014 /****************************************************************************
1015 see if a datagram has the right mailslot name
1016 ***************************************************************************/
1017 BOOL
match_mailslot_name(struct packet_struct
*p
, char *mailslot_name
)
1019 struct dgram_packet
*dgram
= &p
->packet
.dgram
;
1022 buf
= &dgram
->data
[0];
1027 if (memcmp(buf
, mailslot_name
, strlen(mailslot_name
)+1) == 0) {
1035 /****************************************************************************
1036 return the number of bits that match between two 4 character buffers
1037 ***************************************************************************/
1038 static int matching_bits(uchar
*p1
, uchar
*p2
)
1041 for (i
=0; i
<4; i
++) {
1042 if (p1
[i
] != p2
[i
]) break;
1046 if (i
==4) return ret
;
1048 for (j
=0; j
<8; j
++) {
1049 if ((p1
[i
] & (1<<(7-j
))) != (p2
[i
] & (1<<(7-j
)))) break;
1057 static uchar sort_ip
[4];
1059 /****************************************************************************
1060 compare two query reply records
1061 ***************************************************************************/
1062 static int name_query_comp(uchar
*p1
, uchar
*p2
)
1064 return matching_bits(p2
+2, sort_ip
) - matching_bits(p1
+2, sort_ip
);
1067 /****************************************************************************
1068 sort a set of 6 byte name query response records so that the IPs that
1069 have the most leading bits in common with the specified address come first
1070 ***************************************************************************/
1071 void sort_query_replies(char *data
, int n
, struct in_addr ip
)
1075 putip(sort_ip
, (char *)&ip
);
1077 qsort(data
, n
, 6, QSORT_CAST name_query_comp
);
1081 #define TRUNCATE_NETBIOS_NAME 1
1083 /*******************************************************************
1084 convert, possibly using a stupid microsoft-ism which has destroyed
1085 the transport independence of netbios (for CIFS vendors that usually
1086 use the Win95-type methods, not for NT to NT communication, which uses
1087 DCE/RPC and therefore full-length unicode strings...) a dns name into
1090 the netbios name (NOT necessarily null-terminated) is truncated to 15
1093 ******************************************************************/
1094 char *dns_to_netbios_name(char *dns_name
)
1096 static char netbios_name
[16];
1098 StrnCpy(netbios_name
, dns_name
, 15);
1099 netbios_name
[15] = 0;
1101 #ifdef TRUNCATE_NETBIOS_NAME
1102 /* ok. this is because of a stupid microsoft-ism. if the called host
1103 name contains a '.', microsoft clients expect you to truncate the
1104 netbios name up to and including the '.' this even applies, by
1105 mistake, to workgroup (domain) names, which is _really_ daft.
1107 for (i
= 15; i
>= 0; i
--)
1109 if (netbios_name
[i
] == '.')
1111 netbios_name
[i
] = 0;
1115 #endif /* TRUNCATE_NETBIOS_NAME */
1117 return netbios_name
;
1121 /****************************************************************************
1122 interpret the weird netbios "name". Return the name type
1123 ****************************************************************************/
1124 static int name_interpret(char *in
,char *out
)
1127 int len
= (*in
++) / 2;
1131 if (len
> 30 || len
<1) return(0);
1135 if (in
[0] < 'A' || in
[0] > 'P' || in
[1] < 'A' || in
[1] > 'P') {
1139 *out
= ((in
[0]-'A')<<4) + (in
[1]-'A');
1146 #ifdef NETBIOS_SCOPE
1147 /* Handle any scope names */
1150 *out
++ = '.'; /* Scope names are separated by periods */
1151 len
= *(uchar
*)in
++;
1152 StrnCpy(out
, in
, len
);
1161 /****************************************************************************
1162 mangle a name into netbios format
1164 Note: <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
1165 ****************************************************************************/
1166 int name_mangle( char *In
, char *Out
, char name_type
)
1173 extern pstring global_scope
;
1175 /* Safely copy the input string, In, into buf[]. */
1176 (void)memset( buf
, 0, 20 );
1177 if (strcmp(In
,"*") == 0)
1180 (void)slprintf( buf
, sizeof(buf
) - 1, "%-15.15s%c", In
, name_type
);
1182 /* Place the length of the first field into the output buffer. */
1186 /* Now convert the name to the rfc1001/1002 format. */
1187 for( i
= 0; i
< 16; i
++ )
1189 c
= toupper( buf
[i
] );
1190 p
[i
*2] = ( (c
>> 4) & 0x000F ) + 'A';
1191 p
[(i
*2)+1] = (c
& 0x000F) + 'A';
1196 /* Add the scope string. */
1197 for( i
= 0, len
= 0; NULL
!= global_scope
; i
++, len
++ )
1199 switch( global_scope
[i
] )
1205 return( name_len(Out
) );
1212 p
[len
+1] = global_scope
[i
];
1217 return( name_len(Out
) );
1221 /****************************************************************************
1222 find a pointer to a netbios name
1223 ****************************************************************************/
1224 static char *name_ptr(char *buf
,int ofs
)
1226 uchar c
= *(uchar
*)(buf
+ofs
);
1228 if ((c
& 0xC0) == 0xC0)
1230 uint16 l
= RSVAL(buf
, ofs
) & 0x3FFF;
1231 DEBUG(5,("name ptr to pos %d from %d is %s\n",l
,ofs
,buf
+l
));
1238 /****************************************************************************
1239 extract a netbios name from a buf
1240 ****************************************************************************/
1241 int name_extract(char *buf
,int ofs
,char *name
)
1243 char *p
= name_ptr(buf
,ofs
);
1244 int d
= PTR_DIFF(p
,buf
+ofs
);
1246 if (d
< -50 || d
> 50) return(0);
1247 return(name_interpret(p
,name
));
1250 /****************************************************************************
1251 return the total storage length of a mangled name
1252 ****************************************************************************/
1253 int name_len(char *s1
)
1255 /* NOTE: this argument _must_ be unsigned */
1256 uchar
*s
= (uchar
*)s1
;
1259 /* If the two high bits of the byte are set, return 2. */
1260 if (0xC0 == (*s
& 0xC0))
1263 /* Add up the length bytes. */
1264 for (len
= 1; (*s
); s
+= (*s
) + 1) {
1266 SMB_ASSERT(len
< 80);