2 Unix SMB/CIFS implementation.
3 NBT netbios library routines
4 Copyright (C) Andrew Tridgell 1994-1998
5 Copyright (C) Jeremy Allison 2007
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 3 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, see <http://www.gnu.org/licenses/>.
23 #include "libsmb/nmblib.h"
25 static const struct opcode_names
{
26 const char *nmb_opcode_name
;
28 } nmb_header_opcode_names
[] = {
34 {"Refresh(altcode)", 9 },
35 {"Multi-homed Registration", 15 },
39 /****************************************************************************
40 Lookup a nmb opcode name.
41 ****************************************************************************/
43 static const char *lookup_opcode_name( int opcode
)
45 const struct opcode_names
*op_namep
;
48 for(i
= 0; nmb_header_opcode_names
[i
].nmb_opcode_name
!= 0; i
++) {
49 op_namep
= &nmb_header_opcode_names
[i
];
50 if(opcode
== op_namep
->opcode
)
51 return op_namep
->nmb_opcode_name
;
53 return "<unknown opcode>";
56 /****************************************************************************
57 Print out a res_rec structure.
58 ****************************************************************************/
60 static void debug_nmb_res_rec(struct res_rec
*res
, const char *hdr
)
64 DEBUGADD( 4, ( " %s: nmb_name=%s rr_type=%d rr_class=%d ttl=%d\n",
66 nmb_namestr(&res
->rr_name
),
71 if( res
->rdlength
== 0 || res
->rdata
== NULL
)
74 for (i
= 0; i
< res
->rdlength
; i
+= MAX_NETBIOSNAME_LEN
) {
75 DEBUGADD(4, (" %s %3x char ", hdr
, i
));
77 for (j
= 0; j
< MAX_NETBIOSNAME_LEN
; j
++) {
78 unsigned char x
= res
->rdata
[i
+j
];
79 if (x
< 32 || x
> 127)
82 if (i
+j
>= res
->rdlength
)
84 DEBUGADD(4, ("%c", x
));
87 DEBUGADD(4, (" hex "));
89 for (j
= 0; j
< MAX_NETBIOSNAME_LEN
; j
++) {
90 if (i
+j
>= res
->rdlength
)
92 DEBUGADD(4, ("%02X", (unsigned char)res
->rdata
[i
+j
]));
99 /****************************************************************************
100 Process a nmb packet.
101 ****************************************************************************/
103 void debug_nmb_packet(struct packet_struct
*p
)
105 struct nmb_packet
*nmb
= &p
->packet
.nmb
;
107 if( DEBUGLVL( 4 ) ) {
108 dbgtext( "nmb packet from %s(%d) header: id=%d "
109 "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 "
116 "rec_des=%s trunc=%s auth=%s\n",
117 BOOLSTR(nmb
->header
.nm_flags
.bcast
),
118 BOOLSTR(nmb
->header
.nm_flags
.recursion_available
),
119 BOOLSTR(nmb
->header
.nm_flags
.recursion_desired
),
120 BOOLSTR(nmb
->header
.nm_flags
.trunc
),
121 BOOLSTR(nmb
->header
.nm_flags
.authoritative
) );
122 dbgtext( " header: rcode=%d qdcount=%d ancount=%d "
123 "nscount=%d arcount=%d\n",
128 nmb
->header
.arcount
);
131 if (nmb
->header
.qdcount
) {
132 DEBUGADD( 4, ( " question: q_name=%s q_type=%d q_class=%d\n",
133 nmb_namestr(&nmb
->question
.question_name
),
134 nmb
->question
.question_type
,
135 nmb
->question
.question_class
) );
138 if (nmb
->answers
&& nmb
->header
.ancount
) {
139 debug_nmb_res_rec(nmb
->answers
,"answers");
141 if (nmb
->nsrecs
&& nmb
->header
.nscount
) {
142 debug_nmb_res_rec(nmb
->nsrecs
,"nsrecs");
144 if (nmb
->additional
&& nmb
->header
.arcount
) {
145 debug_nmb_res_rec(nmb
->additional
,"additional");
149 /*******************************************************************
150 Handle "compressed" name pointers.
151 ******************************************************************/
153 static bool handle_name_ptrs(unsigned char *ubuf
,int *offset
,int length
,
154 bool *got_pointer
,int *ret
)
158 while ((ubuf
[*offset
] & 0xC0) == 0xC0) {
162 (*offset
) = ((ubuf
[*offset
] & ~0xC0)<<8) | ubuf
[(*offset
)+1];
163 if (loop_count
++ == 10 ||
164 (*offset
) < 0 || (*offset
)>(length
-2)) {
171 /*******************************************************************
172 Parse a nmb name from "compressed" format to something readable
173 return the space taken by the name, or 0 if the name is invalid
174 ******************************************************************/
176 static int parse_nmb_name(char *inbuf
,int ofs
,int length
, struct nmb_name
*name
)
179 unsigned char *ubuf
= (unsigned char *)inbuf
;
181 bool got_pointer
=False
;
185 if (length
- offset
< 2)
188 /* handle initial name pointers */
189 if (!handle_name_ptrs(ubuf
,&offset
,length
,&got_pointer
,&ret
))
196 if ((m
& 0xC0) || offset
+m
+2 > length
)
199 memset((char *)name
,'\0',sizeof(*name
));
201 /* the "compressed" part */
207 c1
= ubuf
[offset
++]-'A';
208 c2
= ubuf
[offset
++]-'A';
209 if ((c1
& 0xF0) || (c2
& 0xF0) || (n
> sizeof(name
->name
)-1))
211 name
->name
[n
++] = (c1
<<4) | c2
;
216 if (n
==MAX_NETBIOSNAME_LEN
) {
217 /* parse out the name type, its always
218 * in the 16th byte of the name */
219 name
->name_type
= ((unsigned char)name
->name
[15]) & 0xff;
221 /* remove trailing spaces */
224 while (n
&& name
->name
[n
]==' ')
228 /* now the domain parts (if any) */
230 while (ubuf
[offset
]) {
231 /* we can have pointers within the domain part as well */
232 if (!handle_name_ptrs(ubuf
,&offset
,length
,&got_pointer
,&ret
))
237 * Don't allow null domain parts.
244 name
->scope
[n
++] = '.';
245 if (m
+2+offset
>length
|| n
+m
+1>sizeof(name
->scope
))
249 name
->scope
[n
++] = (char)ubuf
[offset
++];
252 * Watch for malicious loops.
254 if (loop_count
++ == 10)
257 name
->scope
[n
++] = 0;
262 /****************************************************************************
263 Put a netbios name, padding(s) and a name type into a 16 character buffer.
264 name is already in DOS charset.
265 [15 bytes name + padding][1 byte name type].
266 ****************************************************************************/
268 void put_name(char *dest
, const char *name
, int pad
, unsigned int name_type
)
270 size_t len
= strlen(name
);
272 memcpy(dest
, name
, (len
< MAX_NETBIOSNAME_LEN
) ?
273 len
: MAX_NETBIOSNAME_LEN
- 1);
274 if (len
< MAX_NETBIOSNAME_LEN
- 1) {
275 memset(dest
+ len
, pad
, MAX_NETBIOSNAME_LEN
- 1 - len
);
277 dest
[MAX_NETBIOSNAME_LEN
- 1] = name_type
;
280 /*******************************************************************
281 Put a compressed nmb name into a buffer. Return the length of the
284 Compressed names are really weird. The "compression" doubles the
285 size. The idea is that it also means that compressed names conform
286 to the doman name system. See RFC1002.
288 If buf == NULL this is a length calculation.
289 ******************************************************************/
291 static int put_nmb_name(char *buf
, size_t buflen
, int offset
,struct nmb_name
*name
)
297 if (strcmp(name
->name
,"*") == 0) {
298 /* special case for wildcard name */
299 put_name(buf1
, "*", '\0', name
->name_type
);
301 put_name(buf1
, name
->name
, ' ', name
->name_type
);
305 if (offset
>= buflen
) {
313 for (m
=0;m
<MAX_NETBIOSNAME_LEN
;m
++) {
315 if (offset
+2+2*m
>= buflen
) {
318 buf
[offset
+1+2*m
] = 'A' + ((buf1
[m
]>>4)&0xF);
319 buf
[offset
+2+2*m
] = 'A' + (buf1
[m
]&0xF);
325 if (offset
>= buflen
) {
331 if (name
->scope
[0]) {
332 /* XXXX this scope handling needs testing */
333 size_t scopenamelen
= strlen(name
->scope
) + 1;
336 if (offset
+1+scopenamelen
>= buflen
) {
339 strlcpy(&buf
[offset
+1],name
->scope
,
340 buflen
- (offset
+1));
343 while ((p
= strchr_m(p
,'.'))) {
344 buf
[offset
] = PTR_DIFF(p
,&buf
[offset
+1]);
345 offset
+= (buf
[offset
] + 1);
346 if (offset
+1 >= buflen
) {
351 buf
[offset
] = strlen(&buf
[offset
+1]);
358 /*******************************************************************
359 Useful for debugging messages.
360 ******************************************************************/
362 char *nmb_namestr(const struct nmb_name
*n
)
367 pull_ascii_fstring(name
, n
->name
);
369 result
= talloc_asprintf(talloc_tos(), "%s<%02x>", name
,
372 result
= talloc_asprintf(talloc_tos(), "%s<%02x>.%s", name
,
373 n
->name_type
, n
->scope
);
375 SMB_ASSERT(result
!= NULL
);
379 /*******************************************************************
380 Allocate and parse some resource records.
381 ******************************************************************/
383 static bool parse_alloc_res_rec(char *inbuf
,int *offset
,int length
,
384 struct res_rec
**recs
, int count
)
388 *recs
= SMB_MALLOC_ARRAY(struct res_rec
, count
);
392 memset((char *)*recs
,'\0',sizeof(**recs
)*count
);
394 for (i
=0;i
<count
;i
++) {
395 int l
= parse_nmb_name(inbuf
,*offset
,length
,
396 &(*recs
)[i
].rr_name
);
398 if (!l
|| (*offset
)+10 > length
) {
402 (*recs
)[i
].rr_type
= RSVAL(inbuf
,(*offset
));
403 (*recs
)[i
].rr_class
= RSVAL(inbuf
,(*offset
)+2);
404 (*recs
)[i
].ttl
= RIVAL(inbuf
,(*offset
)+4);
405 (*recs
)[i
].rdlength
= RSVAL(inbuf
,(*offset
)+8);
407 if ((*recs
)[i
].rdlength
>sizeof((*recs
)[i
].rdata
) ||
408 (*offset
)+(*recs
)[i
].rdlength
> length
) {
412 memcpy((*recs
)[i
].rdata
,inbuf
+(*offset
),(*recs
)[i
].rdlength
);
413 (*offset
) += (*recs
)[i
].rdlength
;
418 /*******************************************************************
419 Put a resource record into a packet.
420 If buf == NULL this is a length calculation.
421 ******************************************************************/
423 static int put_res_rec(char *buf
, size_t buflen
, int offset
,struct res_rec
*recs
,int count
)
428 for (i
=0;i
<count
;i
++) {
429 int l
= put_nmb_name(buf
,buflen
,offset
,&recs
[i
].rr_name
);
433 RSSVAL(buf
,offset
,recs
[i
].rr_type
);
434 RSSVAL(buf
,offset
+2,recs
[i
].rr_class
);
435 RSIVAL(buf
,offset
+4,recs
[i
].ttl
);
436 RSSVAL(buf
,offset
+8,recs
[i
].rdlength
);
437 memcpy(buf
+offset
+10,recs
[i
].rdata
,recs
[i
].rdlength
);
439 offset
+= 10+recs
[i
].rdlength
;
440 ret
+= 10+recs
[i
].rdlength
;
446 /*******************************************************************
447 Put a compressed name pointer record into a packet.
448 If buf == NULL this is a length calculation.
449 ******************************************************************/
451 static int put_compressed_name_ptr(unsigned char *buf
,
458 buf
[offset
] = (0xC0 | ((ptr_offset
>> 8) & 0xFF));
459 buf
[offset
+1] = (ptr_offset
& 0xFF);
464 RSSVAL(buf
,offset
,rec
->rr_type
);
465 RSSVAL(buf
,offset
+2,rec
->rr_class
);
466 RSIVAL(buf
,offset
+4,rec
->ttl
);
467 RSSVAL(buf
,offset
+8,rec
->rdlength
);
468 memcpy(buf
+offset
+10,rec
->rdata
,rec
->rdlength
);
470 offset
+= 10+rec
->rdlength
;
471 ret
+= 10+rec
->rdlength
;
476 /*******************************************************************
477 Parse a dgram packet. Return False if the packet can't be parsed
478 or is invalid for some reason, True otherwise.
480 This is documented in section 4.4.1 of RFC1002.
481 ******************************************************************/
483 static bool parse_dgram(char *inbuf
,int length
,struct dgram_packet
*dgram
)
488 memset((char *)dgram
,'\0',sizeof(*dgram
));
493 dgram
->header
.msg_type
= CVAL(inbuf
,0);
494 flags
= CVAL(inbuf
,1);
495 dgram
->header
.flags
.node_type
= (enum node_type
)((flags
>>2)&3);
497 dgram
->header
.flags
.more
= True
;
499 dgram
->header
.flags
.first
= True
;
500 dgram
->header
.dgm_id
= RSVAL(inbuf
,2);
501 putip((char *)&dgram
->header
.source_ip
,inbuf
+4);
502 dgram
->header
.source_port
= RSVAL(inbuf
,8);
503 dgram
->header
.dgm_length
= RSVAL(inbuf
,10);
504 dgram
->header
.packet_offset
= RSVAL(inbuf
,12);
508 if (dgram
->header
.msg_type
== 0x10 ||
509 dgram
->header
.msg_type
== 0x11 ||
510 dgram
->header
.msg_type
== 0x12) {
511 offset
+= parse_nmb_name(inbuf
,offset
,length
,
512 &dgram
->source_name
);
513 offset
+= parse_nmb_name(inbuf
,offset
,length
,
517 if (offset
>= length
|| (length
-offset
> sizeof(dgram
->data
)))
520 dgram
->datasize
= length
-offset
;
521 memcpy(dgram
->data
,inbuf
+offset
,dgram
->datasize
);
523 /* Paranioa. Ensure the last 2 bytes in the dgram buffer are
524 zero. This should be true anyway, just enforce it for
525 paranioa sake. JRA. */
526 SMB_ASSERT(dgram
->datasize
<= (sizeof(dgram
->data
)-2));
527 memset(&dgram
->data
[sizeof(dgram
->data
)-2], '\0', 2);
532 /*******************************************************************
533 Parse a nmb packet. Return False if the packet can't be parsed
534 or is invalid for some reason, True otherwise.
535 ******************************************************************/
537 static bool parse_nmb(char *inbuf
,int length
,struct nmb_packet
*nmb
)
541 memset((char *)nmb
,'\0',sizeof(*nmb
));
546 /* parse the header */
547 nmb
->header
.name_trn_id
= RSVAL(inbuf
,0);
549 DEBUG(10,("parse_nmb: packet id = %d\n", nmb
->header
.name_trn_id
));
551 nmb
->header
.opcode
= (CVAL(inbuf
,2) >> 3) & 0xF;
552 nmb
->header
.response
= ((CVAL(inbuf
,2)>>7)&1)?True
:False
;
553 nm_flags
= ((CVAL(inbuf
,2) & 0x7) << 4) + (CVAL(inbuf
,3)>>4);
554 nmb
->header
.nm_flags
.bcast
= (nm_flags
&1)?True
:False
;
555 nmb
->header
.nm_flags
.recursion_available
= (nm_flags
&8)?True
:False
;
556 nmb
->header
.nm_flags
.recursion_desired
= (nm_flags
&0x10)?True
:False
;
557 nmb
->header
.nm_flags
.trunc
= (nm_flags
&0x20)?True
:False
;
558 nmb
->header
.nm_flags
.authoritative
= (nm_flags
&0x40)?True
:False
;
559 nmb
->header
.rcode
= CVAL(inbuf
,3) & 0xF;
560 nmb
->header
.qdcount
= RSVAL(inbuf
,4);
561 nmb
->header
.ancount
= RSVAL(inbuf
,6);
562 nmb
->header
.nscount
= RSVAL(inbuf
,8);
563 nmb
->header
.arcount
= RSVAL(inbuf
,10);
565 if (nmb
->header
.qdcount
) {
566 offset
= parse_nmb_name(inbuf
,12,length
,
567 &nmb
->question
.question_name
);
571 if (length
- (12+offset
) < 4)
573 nmb
->question
.question_type
= RSVAL(inbuf
,12+offset
);
574 nmb
->question
.question_class
= RSVAL(inbuf
,12+offset
+2);
581 /* and any resource records */
582 if (nmb
->header
.ancount
&&
583 !parse_alloc_res_rec(inbuf
,&offset
,length
,&nmb
->answers
,
584 nmb
->header
.ancount
))
587 if (nmb
->header
.nscount
&&
588 !parse_alloc_res_rec(inbuf
,&offset
,length
,&nmb
->nsrecs
,
589 nmb
->header
.nscount
))
592 if (nmb
->header
.arcount
&&
593 !parse_alloc_res_rec(inbuf
,&offset
,length
,
594 &nmb
->additional
, nmb
->header
.arcount
))
600 /*******************************************************************
601 'Copy constructor' for an nmb packet.
602 ******************************************************************/
604 static struct packet_struct
*copy_nmb_packet(struct packet_struct
*packet
)
606 struct nmb_packet
*nmb
;
607 struct nmb_packet
*copy_nmb
;
608 struct packet_struct
*pkt_copy
;
610 if(( pkt_copy
= SMB_MALLOC_P(struct packet_struct
)) == NULL
) {
611 DEBUG(0,("copy_nmb_packet: malloc fail.\n"));
615 /* Structure copy of entire thing. */
619 /* Ensure this copy is not locked. */
620 pkt_copy
->locked
= False
;
621 pkt_copy
->recv_fd
= -1;
622 pkt_copy
->send_fd
= -1;
624 /* Ensure this copy has no resource records. */
625 nmb
= &packet
->packet
.nmb
;
626 copy_nmb
= &pkt_copy
->packet
.nmb
;
628 copy_nmb
->answers
= NULL
;
629 copy_nmb
->nsrecs
= NULL
;
630 copy_nmb
->additional
= NULL
;
632 /* Now copy any resource records. */
635 if((copy_nmb
->answers
= SMB_MALLOC_ARRAY(
636 struct res_rec
,nmb
->header
.ancount
)) == NULL
)
638 memcpy((char *)copy_nmb
->answers
, (char *)nmb
->answers
,
639 nmb
->header
.ancount
* sizeof(struct res_rec
));
642 if((copy_nmb
->nsrecs
= SMB_MALLOC_ARRAY(
643 struct res_rec
, nmb
->header
.nscount
)) == NULL
)
645 memcpy((char *)copy_nmb
->nsrecs
, (char *)nmb
->nsrecs
,
646 nmb
->header
.nscount
* sizeof(struct res_rec
));
648 if (nmb
->additional
) {
649 if((copy_nmb
->additional
= SMB_MALLOC_ARRAY(
650 struct res_rec
, nmb
->header
.arcount
)) == NULL
)
652 memcpy((char *)copy_nmb
->additional
, (char *)nmb
->additional
,
653 nmb
->header
.arcount
* sizeof(struct res_rec
));
660 SAFE_FREE(copy_nmb
->answers
);
661 SAFE_FREE(copy_nmb
->nsrecs
);
662 SAFE_FREE(copy_nmb
->additional
);
665 DEBUG(0,("copy_nmb_packet: malloc fail in resource records.\n"));
669 /*******************************************************************
670 'Copy constructor' for a dgram packet.
671 ******************************************************************/
673 static struct packet_struct
*copy_dgram_packet(struct packet_struct
*packet
)
675 struct packet_struct
*pkt_copy
;
677 if(( pkt_copy
= SMB_MALLOC_P(struct packet_struct
)) == NULL
) {
678 DEBUG(0,("copy_dgram_packet: malloc fail.\n"));
682 /* Structure copy of entire thing. */
686 /* Ensure this copy is not locked. */
687 pkt_copy
->locked
= False
;
688 pkt_copy
->recv_fd
= -1;
689 pkt_copy
->send_fd
= -1;
691 /* There are no additional pointers in a dgram packet,
696 /*******************************************************************
697 'Copy constructor' for a generic packet.
698 ******************************************************************/
700 struct packet_struct
*copy_packet(struct packet_struct
*packet
)
702 if(packet
->packet_type
== NMB_PACKET
)
703 return copy_nmb_packet(packet
);
704 else if (packet
->packet_type
== DGRAM_PACKET
)
705 return copy_dgram_packet(packet
);
709 /*******************************************************************
710 Free up any resources associated with an nmb packet.
711 ******************************************************************/
713 static void free_nmb_packet(struct nmb_packet
*nmb
)
715 SAFE_FREE(nmb
->answers
);
716 SAFE_FREE(nmb
->nsrecs
);
717 SAFE_FREE(nmb
->additional
);
720 /*******************************************************************
721 Free up any resources associated with a dgram packet.
722 ******************************************************************/
724 static void free_dgram_packet(struct dgram_packet
*nmb
)
726 /* We have nothing to do for a dgram packet. */
729 /*******************************************************************
730 Free up any resources associated with a packet.
731 ******************************************************************/
733 void free_packet(struct packet_struct
*packet
)
737 if (packet
->packet_type
== NMB_PACKET
)
738 free_nmb_packet(&packet
->packet
.nmb
);
739 else if (packet
->packet_type
== DGRAM_PACKET
)
740 free_dgram_packet(&packet
->packet
.dgram
);
741 ZERO_STRUCTPN(packet
);
745 int packet_trn_id(struct packet_struct
*p
)
748 switch (p
->packet_type
) {
750 result
= p
->packet
.nmb
.header
.name_trn_id
;
753 result
= p
->packet
.dgram
.header
.dgm_id
;
761 /*******************************************************************
762 Parse a packet buffer into a packet structure.
763 ******************************************************************/
765 struct packet_struct
*parse_packet(char *buf
,int length
,
766 enum packet_type packet_type
,
770 struct packet_struct
*p
;
773 p
= SMB_MALLOC_P(struct packet_struct
);
777 ZERO_STRUCTP(p
); /* initialize for possible padding */
784 p
->timestamp
= time(NULL
);
785 p
->packet_type
= packet_type
;
787 switch (packet_type
) {
789 ok
= parse_nmb(buf
,length
,&p
->packet
.nmb
);
793 ok
= parse_dgram(buf
,length
,&p
->packet
.dgram
);
805 /*******************************************************************
806 Read a packet from a socket and parse it, returning a packet ready
807 to be used or put on the queue. This assumes a UDP socket.
808 ******************************************************************/
810 struct packet_struct
*read_packet(int fd
,enum packet_type packet_type
)
812 struct packet_struct
*packet
;
813 struct sockaddr_storage sa
;
814 struct sockaddr_in
*si
= (struct sockaddr_in
*)&sa
;
815 char buf
[MAX_DGRAM_SIZE
];
818 length
= read_udp_v4_socket(fd
,buf
,sizeof(buf
),&sa
);
819 if (length
< MIN_DGRAM_SIZE
|| sa
.ss_family
!= AF_INET
) {
823 packet
= parse_packet(buf
,
827 ntohs(si
->sin_port
));
831 packet
->recv_fd
= fd
;
832 packet
->send_fd
= -1;
834 DEBUG(5,("Received a packet of len %d from (%s) port %d\n",
835 length
, inet_ntoa(packet
->ip
), packet
->port
) );
840 /*******************************************************************
841 Send a udp packet on a already open socket.
842 ******************************************************************/
844 static bool send_udp(int fd
,char *buf
,int len
,struct in_addr ip
,int port
)
848 struct sockaddr_in sock_out
;
850 /* set the address and port */
851 memset((char *)&sock_out
,'\0',sizeof(sock_out
));
852 putip((char *)&sock_out
.sin_addr
,(char *)&ip
);
853 sock_out
.sin_port
= htons( port
);
854 sock_out
.sin_family
= AF_INET
;
856 DEBUG( 5, ( "Sending a packet of len %d to (%s) on port %d\n",
857 len
, inet_ntoa(ip
), port
) );
860 * Patch to fix asynch error notifications from Linux kernel.
863 for (i
= 0; i
< 5; i
++) {
864 ret
= (sendto(fd
,buf
,len
,0,(struct sockaddr
*)&sock_out
,
865 sizeof(sock_out
)) >= 0);
866 if (ret
|| errno
!= ECONNREFUSED
)
871 DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n",
872 inet_ntoa(ip
),port
,strerror(errno
)));
877 /*******************************************************************
878 Build a dgram packet ready for sending.
879 If buf == NULL this is a length calculation.
880 ******************************************************************/
882 static int build_dgram(char *buf
, size_t len
, struct dgram_packet
*dgram
)
884 unsigned char *ubuf
= (unsigned char *)buf
;
887 /* put in the header */
889 ubuf
[0] = dgram
->header
.msg_type
;
890 ubuf
[1] = (((int)dgram
->header
.flags
.node_type
)<<2);
891 if (dgram
->header
.flags
.more
)
893 if (dgram
->header
.flags
.first
)
895 RSSVAL(ubuf
,2,dgram
->header
.dgm_id
);
896 putip(ubuf
+4,(char *)&dgram
->header
.source_ip
);
897 RSSVAL(ubuf
,8,dgram
->header
.source_port
);
898 RSSVAL(ubuf
,12,dgram
->header
.packet_offset
);
903 if (dgram
->header
.msg_type
== 0x10 ||
904 dgram
->header
.msg_type
== 0x11 ||
905 dgram
->header
.msg_type
== 0x12) {
906 offset
+= put_nmb_name((char *)ubuf
,len
,offset
,&dgram
->source_name
);
907 offset
+= put_nmb_name((char *)ubuf
,len
,offset
,&dgram
->dest_name
);
911 memcpy(ubuf
+offset
,dgram
->data
,dgram
->datasize
);
913 offset
+= dgram
->datasize
;
915 /* automatically set the dgm_length
916 * NOTE: RFC1002 says the dgm_length does *not*
917 * include the fourteen-byte header. crh
919 dgram
->header
.dgm_length
= (offset
- 14);
921 RSSVAL(ubuf
,10,dgram
->header
.dgm_length
);
927 /*******************************************************************
929 *******************************************************************/
931 void make_nmb_name( struct nmb_name
*n
, const char *name
, int type
)
934 memset( (char *)n
, '\0', sizeof(struct nmb_name
) );
935 fstrcpy(unix_name
, name
);
936 (void)strupper_m(unix_name
);
937 push_ascii(n
->name
, unix_name
, sizeof(n
->name
), STR_TERMINATE
);
938 n
->name_type
= (unsigned int)type
& 0xFF;
939 push_ascii(n
->scope
, lp_netbios_scope(), 64, STR_TERMINATE
);
942 /*******************************************************************
943 Compare two nmb names
944 ******************************************************************/
946 bool nmb_name_equal(struct nmb_name
*n1
, struct nmb_name
*n2
)
948 return ((n1
->name_type
== n2
->name_type
) &&
949 strequal(n1
->name
,n2
->name
) &&
950 strequal(n1
->scope
,n2
->scope
));
953 /*******************************************************************
954 Build a nmb packet ready for sending.
955 If buf == NULL this is a length calculation.
956 ******************************************************************/
958 static int build_nmb(char *buf
, size_t len
, struct nmb_packet
*nmb
)
960 unsigned char *ubuf
= (unsigned char *)buf
;
963 if (len
&& len
< 12) {
967 /* put in the header */
969 RSSVAL(ubuf
,offset
,nmb
->header
.name_trn_id
);
970 ubuf
[offset
+2] = (nmb
->header
.opcode
& 0xF) << 3;
971 if (nmb
->header
.response
)
972 ubuf
[offset
+2] |= (1<<7);
973 if (nmb
->header
.nm_flags
.authoritative
&&
974 nmb
->header
.response
)
975 ubuf
[offset
+2] |= 0x4;
976 if (nmb
->header
.nm_flags
.trunc
)
977 ubuf
[offset
+2] |= 0x2;
978 if (nmb
->header
.nm_flags
.recursion_desired
)
979 ubuf
[offset
+2] |= 0x1;
980 if (nmb
->header
.nm_flags
.recursion_available
&&
981 nmb
->header
.response
)
982 ubuf
[offset
+3] |= 0x80;
983 if (nmb
->header
.nm_flags
.bcast
)
984 ubuf
[offset
+3] |= 0x10;
985 ubuf
[offset
+3] |= (nmb
->header
.rcode
& 0xF);
987 RSSVAL(ubuf
,offset
+4,nmb
->header
.qdcount
);
988 RSSVAL(ubuf
,offset
+6,nmb
->header
.ancount
);
989 RSSVAL(ubuf
,offset
+8,nmb
->header
.nscount
);
990 RSSVAL(ubuf
,offset
+10,nmb
->header
.arcount
);
994 if (nmb
->header
.qdcount
) {
995 /* XXXX this doesn't handle a qdcount of > 1 */
998 int extra
= put_nmb_name(NULL
,0,offset
,
999 &nmb
->question
.question_name
);
1000 if (offset
+ extra
> len
) {
1004 offset
+= put_nmb_name((char *)ubuf
,len
,offset
,
1005 &nmb
->question
.question_name
);
1007 RSSVAL(ubuf
,offset
,nmb
->question
.question_type
);
1008 RSSVAL(ubuf
,offset
+2,nmb
->question
.question_class
);
1013 if (nmb
->header
.ancount
) {
1016 int extra
= put_res_rec(NULL
,0,offset
,nmb
->answers
,
1017 nmb
->header
.ancount
);
1018 if (offset
+ extra
> len
) {
1022 offset
+= put_res_rec((char *)ubuf
,len
,offset
,nmb
->answers
,
1023 nmb
->header
.ancount
);
1026 if (nmb
->header
.nscount
) {
1029 int extra
= put_res_rec(NULL
,0,offset
,nmb
->nsrecs
,
1030 nmb
->header
.nscount
);
1031 if (offset
+ extra
> len
) {
1035 offset
+= put_res_rec((char *)ubuf
,len
,offset
,nmb
->nsrecs
,
1036 nmb
->header
.nscount
);
1040 * The spec says we must put compressed name pointers
1041 * in the following outgoing packets :
1042 * NAME_REGISTRATION_REQUEST, NAME_REFRESH_REQUEST,
1043 * NAME_RELEASE_REQUEST.
1046 if((nmb
->header
.response
== False
) &&
1047 ((nmb
->header
.opcode
== NMB_NAME_REG_OPCODE
) ||
1048 (nmb
->header
.opcode
== NMB_NAME_RELEASE_OPCODE
) ||
1049 (nmb
->header
.opcode
== NMB_NAME_REFRESH_OPCODE_8
) ||
1050 (nmb
->header
.opcode
== NMB_NAME_REFRESH_OPCODE_9
) ||
1051 (nmb
->header
.opcode
== NMB_NAME_MULTIHOMED_REG_OPCODE
)) &&
1052 (nmb
->header
.arcount
== 1)) {
1056 int extra
= put_compressed_name_ptr(NULL
,offset
,
1057 nmb
->additional
,12);
1058 if (offset
+ extra
> len
) {
1062 offset
+= put_compressed_name_ptr(ubuf
,offset
,
1063 nmb
->additional
,12);
1064 } else if (nmb
->header
.arcount
) {
1067 int extra
= put_res_rec(NULL
,0,offset
,nmb
->additional
,
1068 nmb
->header
.arcount
);
1069 if (offset
+ extra
> len
) {
1073 offset
+= put_res_rec((char *)ubuf
,len
,offset
,nmb
->additional
,
1074 nmb
->header
.arcount
);
1079 /*******************************************************************
1081 ******************************************************************/
1083 int build_packet(char *buf
, size_t buflen
, struct packet_struct
*p
)
1087 switch (p
->packet_type
) {
1089 len
= build_nmb(buf
,buflen
,&p
->packet
.nmb
);
1093 len
= build_dgram(buf
,buflen
,&p
->packet
.dgram
);
1100 /*******************************************************************
1101 Send a packet_struct.
1102 ******************************************************************/
1104 bool send_packet(struct packet_struct
*p
)
1109 memset(buf
,'\0',sizeof(buf
));
1111 len
= build_packet(buf
, sizeof(buf
), p
);
1116 return(send_udp(p
->send_fd
,buf
,len
,p
->ip
,p
->port
));
1119 /****************************************************************************
1120 Receive a UDP/138 packet either via UDP or from the unexpected packet
1121 queue. The packet must be a reply packet and have the specified mailslot name
1122 The timeout is in milliseconds.
1123 ***************************************************************************/
1125 /****************************************************************************
1126 See if a datagram has the right mailslot name.
1127 ***************************************************************************/
1129 bool match_mailslot_name(struct packet_struct
*p
, const char *mailslot_name
)
1131 struct dgram_packet
*dgram
= &p
->packet
.dgram
;
1134 buf
= &dgram
->data
[0];
1139 if (memcmp(buf
, mailslot_name
, strlen(mailslot_name
)+1) == 0) {
1146 /****************************************************************************
1147 Return the number of bits that match between two len character buffers
1148 ***************************************************************************/
1150 int matching_len_bits(const unsigned char *p1
, const unsigned char *p2
, size_t len
)
1154 for (i
=0; i
<len
; i
++) {
1163 for (j
=0; j
<8; j
++) {
1164 if ((p1
[i
] & (1<<(7-j
))) != (p2
[i
] & (1<<(7-j
))))
1172 static unsigned char sort_ip
[4];
1174 /****************************************************************************
1175 Compare two query reply records.
1176 ***************************************************************************/
1178 static int name_query_comp(unsigned char *p1
, unsigned char *p2
)
1180 return matching_len_bits(p2
+2, sort_ip
, 4) -
1181 matching_len_bits(p1
+2, sort_ip
, 4);
1184 /****************************************************************************
1185 Sort a set of 6 byte name query response records so that the IPs that
1186 have the most leading bits in common with the specified address come first.
1187 ***************************************************************************/
1189 void sort_query_replies(char *data
, int n
, struct in_addr ip
)
1194 putip(sort_ip
, (char *)&ip
);
1197 this can't use TYPESAFE_QSORT() as the types are wrong.
1198 It should be fixed to use a real type instead of char*
1200 qsort(data
, n
, 6, QSORT_CAST name_query_comp
);
1203 /****************************************************************************
1204 Interpret the weird netbios "name" into a unix fstring. Return the name type.
1205 Returns -1 on error.
1206 ****************************************************************************/
1208 static int name_interpret(unsigned char *buf
, size_t buf_len
,
1209 unsigned char *in
, fstring name
)
1211 unsigned char *end_ptr
= buf
+ buf_len
;
1215 unsigned char *out
= (unsigned char *)out_string
;
1219 if (in
>= end_ptr
) {
1229 if (&in
[1] >= end_ptr
) {
1232 if (in
[0] < 'A' || in
[0] > 'P' || in
[1] < 'A' || in
[1] > 'P') {
1236 *out
= ((in
[0]-'A')<<4) + (in
[1]-'A');
1239 if (PTR_DIFF(out
,out_string
) >= sizeof(fstring
)) {
1246 pull_ascii_fstring(name
, out_string
);
1251 /****************************************************************************
1252 Mangle a name into netbios format.
1253 Note: <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
1254 ****************************************************************************/
1256 char *name_mangle(TALLOC_CTX
*mem_ctx
, const char *In
, char name_type
)
1264 result
= talloc_array(mem_ctx
, char, 33 + strlen(lp_netbios_scope()) + 2);
1265 if (result
== NULL
) {
1270 /* Safely copy the input string, In, into buf[]. */
1271 if (strcmp(In
,"*") == 0)
1272 put_name(buf
, "*", '\0', 0x00);
1274 /* We use an fstring here as mb dos names can expend x3 when
1279 pull_ascii_fstring(buf_unix
, In
);
1280 if (!strupper_m(buf_unix
)) {
1284 push_ascii_nstring(buf_dos
, buf_unix
);
1285 put_name(buf
, buf_dos
, ' ', name_type
);
1288 /* Place the length of the first field into the output buffer. */
1292 /* Now convert the name to the rfc1001/1002 format. */
1293 for( i
= 0; i
< MAX_NETBIOSNAME_LEN
; i
++ ) {
1294 p
[i
*2] = ( (buf
[i
] >> 4) & 0x000F ) + 'A';
1295 p
[(i
*2)+1] = (buf
[i
] & 0x000F) + 'A';
1300 /* Add the scope string. */
1301 for( i
= 0, len
= 0; *(lp_netbios_scope()) != '\0'; i
++, len
++ ) {
1302 switch( (lp_netbios_scope())[i
] ) {
1314 p
[len
+1] = (lp_netbios_scope())[i
];
1322 /****************************************************************************
1323 Find a pointer to a netbios name.
1324 ****************************************************************************/
1326 static unsigned char *name_ptr(unsigned char *buf
, size_t buf_len
, unsigned int ofs
)
1328 unsigned char c
= 0;
1330 if (ofs
> buf_len
|| buf_len
< 1) {
1334 c
= *(unsigned char *)(buf
+ofs
);
1335 if ((c
& 0xC0) == 0xC0) {
1338 if (ofs
> buf_len
- 1) {
1341 l
= RSVAL(buf
, ofs
) & 0x3FFF;
1345 DEBUG(5,("name ptr to pos %d from %d is %s\n",l
,ofs
,buf
+l
));
1352 /****************************************************************************
1353 Extract a netbios name from a buf (into a unix string) return name type.
1354 Returns -1 on error.
1355 ****************************************************************************/
1357 int name_extract(unsigned char *buf
, size_t buf_len
, unsigned int ofs
, fstring name
)
1359 unsigned char *p
= name_ptr(buf
,buf_len
,ofs
);
1365 return(name_interpret(buf
,buf_len
,p
,name
));
1368 /****************************************************************************
1369 Return the total storage length of a mangled name.
1370 Returns -1 on error.
1371 ****************************************************************************/
1373 int name_len(unsigned char *s1
, size_t buf_len
)
1375 /* NOTE: this argument _must_ be unsigned */
1376 unsigned char *s
= (unsigned char *)s1
;
1382 /* If the two high bits of the byte are set, return 2. */
1383 if (0xC0 == (*s
& 0xC0)) {
1390 /* Add up the length bytes. */
1391 for (len
= 1; (*s
); s
+= (*s
) + 1) {
1393 if (len
> buf_len
) {