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/>.
24 int num_good_sends
= 0;
25 int num_good_receives
= 0;
27 static const struct opcode_names
{
28 const char *nmb_opcode_name
;
30 } nmb_header_opcode_names
[] = {
36 {"Refresh(altcode)", 9 },
37 {"Multi-homed Registration", 15 },
41 /****************************************************************************
42 Lookup a nmb opcode name.
43 ****************************************************************************/
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 ****************************************************************************/
62 static void debug_nmb_res_rec(struct res_rec
*res
, const char *hdr
)
66 DEBUGADD( 4, ( " %s: nmb_name=%s rr_type=%d rr_class=%d ttl=%d\n",
68 nmb_namestr(&res
->rr_name
),
73 if( res
->rdlength
== 0 || res
->rdata
== NULL
)
76 for (i
= 0; i
< res
->rdlength
; i
+= MAX_NETBIOSNAME_LEN
) {
77 DEBUGADD(4, (" %s %3x char ", hdr
, i
));
79 for (j
= 0; j
< MAX_NETBIOSNAME_LEN
; j
++) {
80 unsigned char x
= res
->rdata
[i
+j
];
81 if (x
< 32 || x
> 127)
84 if (i
+j
>= res
->rdlength
)
86 DEBUGADD(4, ("%c", x
));
89 DEBUGADD(4, (" hex "));
91 for (j
= 0; j
< MAX_NETBIOSNAME_LEN
; j
++) {
92 if (i
+j
>= res
->rdlength
)
94 DEBUGADD(4, ("%02X", (unsigned char)res
->rdata
[i
+j
]));
101 /****************************************************************************
102 Process a nmb packet.
103 ****************************************************************************/
105 void debug_nmb_packet(struct packet_struct
*p
)
107 struct nmb_packet
*nmb
= &p
->packet
.nmb
;
109 if( DEBUGLVL( 4 ) ) {
110 dbgtext( "nmb packet from %s(%d) header: id=%d "
111 "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 "
118 "rec_des=%s trunc=%s auth=%s\n",
119 BOOLSTR(nmb
->header
.nm_flags
.bcast
),
120 BOOLSTR(nmb
->header
.nm_flags
.recursion_available
),
121 BOOLSTR(nmb
->header
.nm_flags
.recursion_desired
),
122 BOOLSTR(nmb
->header
.nm_flags
.trunc
),
123 BOOLSTR(nmb
->header
.nm_flags
.authoritative
) );
124 dbgtext( " header: rcode=%d qdcount=%d ancount=%d "
125 "nscount=%d arcount=%d\n",
130 nmb
->header
.arcount
);
133 if (nmb
->header
.qdcount
) {
134 DEBUGADD( 4, ( " question: q_name=%s q_type=%d q_class=%d\n",
135 nmb_namestr(&nmb
->question
.question_name
),
136 nmb
->question
.question_type
,
137 nmb
->question
.question_class
) );
140 if (nmb
->answers
&& nmb
->header
.ancount
) {
141 debug_nmb_res_rec(nmb
->answers
,"answers");
143 if (nmb
->nsrecs
&& nmb
->header
.nscount
) {
144 debug_nmb_res_rec(nmb
->nsrecs
,"nsrecs");
146 if (nmb
->additional
&& nmb
->header
.arcount
) {
147 debug_nmb_res_rec(nmb
->additional
,"additional");
151 /*******************************************************************
152 Handle "compressed" name pointers.
153 ******************************************************************/
155 static bool handle_name_ptrs(unsigned char *ubuf
,int *offset
,int length
,
156 bool *got_pointer
,int *ret
)
160 while ((ubuf
[*offset
] & 0xC0) == 0xC0) {
164 (*offset
) = ((ubuf
[*offset
] & ~0xC0)<<8) | ubuf
[(*offset
)+1];
165 if (loop_count
++ == 10 ||
166 (*offset
) < 0 || (*offset
)>(length
-2)) {
173 /*******************************************************************
174 Parse a nmb name from "compressed" format to something readable
175 return the space taken by the name, or 0 if the name is invalid
176 ******************************************************************/
178 static int parse_nmb_name(char *inbuf
,int ofs
,int length
, struct nmb_name
*name
)
181 unsigned char *ubuf
= (unsigned char *)inbuf
;
183 bool got_pointer
=False
;
187 if (length
- offset
< 2)
190 /* handle initial name pointers */
191 if (!handle_name_ptrs(ubuf
,&offset
,length
,&got_pointer
,&ret
))
198 if ((m
& 0xC0) || offset
+m
+2 > length
)
201 memset((char *)name
,'\0',sizeof(*name
));
203 /* the "compressed" part */
209 c1
= ubuf
[offset
++]-'A';
210 c2
= ubuf
[offset
++]-'A';
211 if ((c1
& 0xF0) || (c2
& 0xF0) || (n
> sizeof(name
->name
)-1))
213 name
->name
[n
++] = (c1
<<4) | c2
;
218 if (n
==MAX_NETBIOSNAME_LEN
) {
219 /* parse out the name type, its always
220 * in the 16th byte of the name */
221 name
->name_type
= ((unsigned char)name
->name
[15]) & 0xff;
223 /* remove trailing spaces */
226 while (n
&& name
->name
[n
]==' ')
230 /* now the domain parts (if any) */
232 while (ubuf
[offset
]) {
233 /* we can have pointers within the domain part as well */
234 if (!handle_name_ptrs(ubuf
,&offset
,length
,&got_pointer
,&ret
))
239 * Don't allow null domain parts.
246 name
->scope
[n
++] = '.';
247 if (m
+2+offset
>length
|| n
+m
+1>sizeof(name
->scope
))
251 name
->scope
[n
++] = (char)ubuf
[offset
++];
254 * Watch for malicious loops.
256 if (loop_count
++ == 10)
259 name
->scope
[n
++] = 0;
264 /****************************************************************************
265 Put a netbios name, padding(s) and a name type into a 16 character buffer.
266 name is already in DOS charset.
267 [15 bytes name + padding][1 byte name type].
268 ****************************************************************************/
270 void put_name(char *dest
, const char *name
, int pad
, unsigned int name_type
)
272 size_t len
= strlen(name
);
274 memcpy(dest
, name
, (len
< MAX_NETBIOSNAME_LEN
) ?
275 len
: MAX_NETBIOSNAME_LEN
- 1);
276 if (len
< MAX_NETBIOSNAME_LEN
- 1) {
277 memset(dest
+ len
, pad
, MAX_NETBIOSNAME_LEN
- 1 - len
);
279 dest
[MAX_NETBIOSNAME_LEN
- 1] = name_type
;
282 /*******************************************************************
283 Put a compressed nmb name into a buffer. Return the length of the
286 Compressed names are really weird. The "compression" doubles the
287 size. The idea is that it also means that compressed names conform
288 to the doman name system. See RFC1002.
290 If buf == NULL this is a length calculation.
291 ******************************************************************/
293 static int put_nmb_name(char *buf
,int offset
,struct nmb_name
*name
)
299 if (strcmp(name
->name
,"*") == 0) {
300 /* special case for wildcard name */
301 put_name(buf1
, "*", '\0', name
->name_type
);
303 put_name(buf1
, name
->name
, ' ', name
->name_type
);
312 for (m
=0;m
<MAX_NETBIOSNAME_LEN
;m
++) {
314 buf
[offset
+1+2*m
] = 'A' + ((buf1
[m
]>>4)&0xF);
315 buf
[offset
+2+2*m
] = 'A' + (buf1
[m
]&0xF);
324 if (name
->scope
[0]) {
325 /* XXXX this scope handling needs testing */
326 ret
+= strlen(name
->scope
) + 1;
328 safe_strcpy(&buf
[offset
+1],name
->scope
,
329 sizeof(name
->scope
));
332 while ((p
= strchr_m(p
,'.'))) {
333 buf
[offset
] = PTR_DIFF(p
,&buf
[offset
+1]);
334 offset
+= (buf
[offset
] + 1);
337 buf
[offset
] = strlen(&buf
[offset
+1]);
344 /*******************************************************************
345 Useful for debugging messages.
346 ******************************************************************/
348 char *nmb_namestr(const struct nmb_name
*n
)
353 pull_ascii_fstring(name
, n
->name
);
355 result
= talloc_asprintf(talloc_tos(), "%s<%02x>", name
,
358 result
= talloc_asprintf(talloc_tos(), "%s<%02x>.%s", name
,
359 n
->name_type
, n
->scope
);
361 SMB_ASSERT(result
!= NULL
);
365 /*******************************************************************
366 Allocate and parse some resource records.
367 ******************************************************************/
369 static bool parse_alloc_res_rec(char *inbuf
,int *offset
,int length
,
370 struct res_rec
**recs
, int count
)
374 *recs
= SMB_MALLOC_ARRAY(struct res_rec
, count
);
378 memset((char *)*recs
,'\0',sizeof(**recs
)*count
);
380 for (i
=0;i
<count
;i
++) {
381 int l
= parse_nmb_name(inbuf
,*offset
,length
,
382 &(*recs
)[i
].rr_name
);
384 if (!l
|| (*offset
)+10 > length
) {
388 (*recs
)[i
].rr_type
= RSVAL(inbuf
,(*offset
));
389 (*recs
)[i
].rr_class
= RSVAL(inbuf
,(*offset
)+2);
390 (*recs
)[i
].ttl
= RIVAL(inbuf
,(*offset
)+4);
391 (*recs
)[i
].rdlength
= RSVAL(inbuf
,(*offset
)+8);
393 if ((*recs
)[i
].rdlength
>sizeof((*recs
)[i
].rdata
) ||
394 (*offset
)+(*recs
)[i
].rdlength
> length
) {
398 memcpy((*recs
)[i
].rdata
,inbuf
+(*offset
),(*recs
)[i
].rdlength
);
399 (*offset
) += (*recs
)[i
].rdlength
;
404 /*******************************************************************
405 Put a resource record into a packet.
406 If buf == NULL this is a length calculation.
407 ******************************************************************/
409 static int put_res_rec(char *buf
,int offset
,struct res_rec
*recs
,int count
)
414 for (i
=0;i
<count
;i
++) {
415 int l
= put_nmb_name(buf
,offset
,&recs
[i
].rr_name
);
419 RSSVAL(buf
,offset
,recs
[i
].rr_type
);
420 RSSVAL(buf
,offset
+2,recs
[i
].rr_class
);
421 RSIVAL(buf
,offset
+4,recs
[i
].ttl
);
422 RSSVAL(buf
,offset
+8,recs
[i
].rdlength
);
423 memcpy(buf
+offset
+10,recs
[i
].rdata
,recs
[i
].rdlength
);
425 offset
+= 10+recs
[i
].rdlength
;
426 ret
+= 10+recs
[i
].rdlength
;
432 /*******************************************************************
433 Put a compressed name pointer record into a packet.
434 If buf == NULL this is a length calculation.
435 ******************************************************************/
437 static int put_compressed_name_ptr(unsigned char *buf
,
444 buf
[offset
] = (0xC0 | ((ptr_offset
>> 8) & 0xFF));
445 buf
[offset
+1] = (ptr_offset
& 0xFF);
450 RSSVAL(buf
,offset
,rec
->rr_type
);
451 RSSVAL(buf
,offset
+2,rec
->rr_class
);
452 RSIVAL(buf
,offset
+4,rec
->ttl
);
453 RSSVAL(buf
,offset
+8,rec
->rdlength
);
454 memcpy(buf
+offset
+10,rec
->rdata
,rec
->rdlength
);
456 offset
+= 10+rec
->rdlength
;
457 ret
+= 10+rec
->rdlength
;
462 /*******************************************************************
463 Parse a dgram packet. Return False if the packet can't be parsed
464 or is invalid for some reason, True otherwise.
466 This is documented in section 4.4.1 of RFC1002.
467 ******************************************************************/
469 static bool parse_dgram(char *inbuf
,int length
,struct dgram_packet
*dgram
)
474 memset((char *)dgram
,'\0',sizeof(*dgram
));
479 dgram
->header
.msg_type
= CVAL(inbuf
,0);
480 flags
= CVAL(inbuf
,1);
481 dgram
->header
.flags
.node_type
= (enum node_type
)((flags
>>2)&3);
483 dgram
->header
.flags
.more
= True
;
485 dgram
->header
.flags
.first
= True
;
486 dgram
->header
.dgm_id
= RSVAL(inbuf
,2);
487 putip((char *)&dgram
->header
.source_ip
,inbuf
+4);
488 dgram
->header
.source_port
= RSVAL(inbuf
,8);
489 dgram
->header
.dgm_length
= RSVAL(inbuf
,10);
490 dgram
->header
.packet_offset
= RSVAL(inbuf
,12);
494 if (dgram
->header
.msg_type
== 0x10 ||
495 dgram
->header
.msg_type
== 0x11 ||
496 dgram
->header
.msg_type
== 0x12) {
497 offset
+= parse_nmb_name(inbuf
,offset
,length
,
498 &dgram
->source_name
);
499 offset
+= parse_nmb_name(inbuf
,offset
,length
,
503 if (offset
>= length
|| (length
-offset
> sizeof(dgram
->data
)))
506 dgram
->datasize
= length
-offset
;
507 memcpy(dgram
->data
,inbuf
+offset
,dgram
->datasize
);
509 /* Paranioa. Ensure the last 2 bytes in the dgram buffer are
510 zero. This should be true anyway, just enforce it for
511 paranioa sake. JRA. */
512 SMB_ASSERT(dgram
->datasize
<= (sizeof(dgram
->data
)-2));
513 memset(&dgram
->data
[sizeof(dgram
->data
)-2], '\0', 2);
518 /*******************************************************************
519 Parse a nmb packet. Return False if the packet can't be parsed
520 or is invalid for some reason, True otherwise.
521 ******************************************************************/
523 static bool parse_nmb(char *inbuf
,int length
,struct nmb_packet
*nmb
)
527 memset((char *)nmb
,'\0',sizeof(*nmb
));
532 /* parse the header */
533 nmb
->header
.name_trn_id
= RSVAL(inbuf
,0);
535 DEBUG(10,("parse_nmb: packet id = %d\n", nmb
->header
.name_trn_id
));
537 nmb
->header
.opcode
= (CVAL(inbuf
,2) >> 3) & 0xF;
538 nmb
->header
.response
= ((CVAL(inbuf
,2)>>7)&1)?True
:False
;
539 nm_flags
= ((CVAL(inbuf
,2) & 0x7) << 4) + (CVAL(inbuf
,3)>>4);
540 nmb
->header
.nm_flags
.bcast
= (nm_flags
&1)?True
:False
;
541 nmb
->header
.nm_flags
.recursion_available
= (nm_flags
&8)?True
:False
;
542 nmb
->header
.nm_flags
.recursion_desired
= (nm_flags
&0x10)?True
:False
;
543 nmb
->header
.nm_flags
.trunc
= (nm_flags
&0x20)?True
:False
;
544 nmb
->header
.nm_flags
.authoritative
= (nm_flags
&0x40)?True
:False
;
545 nmb
->header
.rcode
= CVAL(inbuf
,3) & 0xF;
546 nmb
->header
.qdcount
= RSVAL(inbuf
,4);
547 nmb
->header
.ancount
= RSVAL(inbuf
,6);
548 nmb
->header
.nscount
= RSVAL(inbuf
,8);
549 nmb
->header
.arcount
= RSVAL(inbuf
,10);
551 if (nmb
->header
.qdcount
) {
552 offset
= parse_nmb_name(inbuf
,12,length
,
553 &nmb
->question
.question_name
);
557 if (length
- (12+offset
) < 4)
559 nmb
->question
.question_type
= RSVAL(inbuf
,12+offset
);
560 nmb
->question
.question_class
= RSVAL(inbuf
,12+offset
+2);
567 /* and any resource records */
568 if (nmb
->header
.ancount
&&
569 !parse_alloc_res_rec(inbuf
,&offset
,length
,&nmb
->answers
,
570 nmb
->header
.ancount
))
573 if (nmb
->header
.nscount
&&
574 !parse_alloc_res_rec(inbuf
,&offset
,length
,&nmb
->nsrecs
,
575 nmb
->header
.nscount
))
578 if (nmb
->header
.arcount
&&
579 !parse_alloc_res_rec(inbuf
,&offset
,length
,
580 &nmb
->additional
, nmb
->header
.arcount
))
586 /*******************************************************************
587 'Copy constructor' for an nmb packet.
588 ******************************************************************/
590 static struct packet_struct
*copy_nmb_packet(struct packet_struct
*packet
)
592 struct nmb_packet
*nmb
;
593 struct nmb_packet
*copy_nmb
;
594 struct packet_struct
*pkt_copy
;
596 if(( pkt_copy
= SMB_MALLOC_P(struct packet_struct
)) == NULL
) {
597 DEBUG(0,("copy_nmb_packet: malloc fail.\n"));
601 /* Structure copy of entire thing. */
605 /* Ensure this copy is not locked. */
606 pkt_copy
->locked
= False
;
608 /* Ensure this copy has no resource records. */
609 nmb
= &packet
->packet
.nmb
;
610 copy_nmb
= &pkt_copy
->packet
.nmb
;
612 copy_nmb
->answers
= NULL
;
613 copy_nmb
->nsrecs
= NULL
;
614 copy_nmb
->additional
= NULL
;
616 /* Now copy any resource records. */
619 if((copy_nmb
->answers
= SMB_MALLOC_ARRAY(
620 struct res_rec
,nmb
->header
.ancount
)) == NULL
)
622 memcpy((char *)copy_nmb
->answers
, (char *)nmb
->answers
,
623 nmb
->header
.ancount
* sizeof(struct res_rec
));
626 if((copy_nmb
->nsrecs
= SMB_MALLOC_ARRAY(
627 struct res_rec
, nmb
->header
.nscount
)) == NULL
)
629 memcpy((char *)copy_nmb
->nsrecs
, (char *)nmb
->nsrecs
,
630 nmb
->header
.nscount
* sizeof(struct res_rec
));
632 if (nmb
->additional
) {
633 if((copy_nmb
->additional
= SMB_MALLOC_ARRAY(
634 struct res_rec
, nmb
->header
.arcount
)) == NULL
)
636 memcpy((char *)copy_nmb
->additional
, (char *)nmb
->additional
,
637 nmb
->header
.arcount
* sizeof(struct res_rec
));
644 SAFE_FREE(copy_nmb
->answers
);
645 SAFE_FREE(copy_nmb
->nsrecs
);
646 SAFE_FREE(copy_nmb
->additional
);
649 DEBUG(0,("copy_nmb_packet: malloc fail in resource records.\n"));
653 /*******************************************************************
654 'Copy constructor' for a dgram packet.
655 ******************************************************************/
657 static struct packet_struct
*copy_dgram_packet(struct packet_struct
*packet
)
659 struct packet_struct
*pkt_copy
;
661 if(( pkt_copy
= SMB_MALLOC_P(struct packet_struct
)) == NULL
) {
662 DEBUG(0,("copy_dgram_packet: malloc fail.\n"));
666 /* Structure copy of entire thing. */
670 /* Ensure this copy is not locked. */
671 pkt_copy
->locked
= False
;
673 /* There are no additional pointers in a dgram packet,
678 /*******************************************************************
679 'Copy constructor' for a generic packet.
680 ******************************************************************/
682 struct packet_struct
*copy_packet(struct packet_struct
*packet
)
684 if(packet
->packet_type
== NMB_PACKET
)
685 return copy_nmb_packet(packet
);
686 else if (packet
->packet_type
== DGRAM_PACKET
)
687 return copy_dgram_packet(packet
);
691 /*******************************************************************
692 Free up any resources associated with an nmb packet.
693 ******************************************************************/
695 static void free_nmb_packet(struct nmb_packet
*nmb
)
697 SAFE_FREE(nmb
->answers
);
698 SAFE_FREE(nmb
->nsrecs
);
699 SAFE_FREE(nmb
->additional
);
702 /*******************************************************************
703 Free up any resources associated with a dgram packet.
704 ******************************************************************/
706 static void free_dgram_packet(struct dgram_packet
*nmb
)
708 /* We have nothing to do for a dgram packet. */
711 /*******************************************************************
712 Free up any resources associated with a packet.
713 ******************************************************************/
715 void free_packet(struct packet_struct
*packet
)
719 if (packet
->packet_type
== NMB_PACKET
)
720 free_nmb_packet(&packet
->packet
.nmb
);
721 else if (packet
->packet_type
== DGRAM_PACKET
)
722 free_dgram_packet(&packet
->packet
.dgram
);
723 ZERO_STRUCTPN(packet
);
727 /*******************************************************************
728 Parse a packet buffer into a packet structure.
729 ******************************************************************/
731 struct packet_struct
*parse_packet(char *buf
,int length
,
732 enum packet_type packet_type
,
736 struct packet_struct
*p
;
739 p
= SMB_MALLOC_P(struct packet_struct
);
743 ZERO_STRUCTP(p
); /* initialize for possible padding */
750 p
->timestamp
= time(NULL
);
751 p
->packet_type
= packet_type
;
753 switch (packet_type
) {
755 ok
= parse_nmb(buf
,length
,&p
->packet
.nmb
);
759 ok
= parse_dgram(buf
,length
,&p
->packet
.dgram
);
771 /*******************************************************************
772 Read a packet from a socket and parse it, returning a packet ready
773 to be used or put on the queue. This assumes a UDP socket.
774 ******************************************************************/
776 struct packet_struct
*read_packet(int fd
,enum packet_type packet_type
)
778 struct packet_struct
*packet
;
779 struct sockaddr_storage sa
;
780 struct sockaddr_in
*si
= (struct sockaddr_in
*)&sa
;
781 char buf
[MAX_DGRAM_SIZE
];
784 length
= read_udp_v4_socket(fd
,buf
,sizeof(buf
),&sa
);
785 if (length
< MIN_DGRAM_SIZE
|| sa
.ss_family
!= AF_INET
) {
789 packet
= parse_packet(buf
,
793 ntohs(si
->sin_port
));
801 DEBUG(5,("Received a packet of len %d from (%s) port %d\n",
802 length
, inet_ntoa(packet
->ip
), packet
->port
) );
807 /*******************************************************************
808 Send a udp packet on a already open socket.
809 ******************************************************************/
811 static bool send_udp(int fd
,char *buf
,int len
,struct in_addr ip
,int port
)
815 struct sockaddr_in sock_out
;
817 /* set the address and port */
818 memset((char *)&sock_out
,'\0',sizeof(sock_out
));
819 putip((char *)&sock_out
.sin_addr
,(char *)&ip
);
820 sock_out
.sin_port
= htons( port
);
821 sock_out
.sin_family
= AF_INET
;
823 DEBUG( 5, ( "Sending a packet of len %d to (%s) on port %d\n",
824 len
, inet_ntoa(ip
), port
) );
827 * Patch to fix asynch error notifications from Linux kernel.
830 for (i
= 0; i
< 5; i
++) {
831 ret
= (sendto(fd
,buf
,len
,0,(struct sockaddr
*)&sock_out
,
832 sizeof(sock_out
)) >= 0);
833 if (ret
|| errno
!= ECONNREFUSED
)
838 DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n",
839 inet_ntoa(ip
),port
,strerror(errno
)));
847 /*******************************************************************
848 Build a dgram packet ready for sending.
849 If buf == NULL this is a length calculation.
850 ******************************************************************/
852 static int build_dgram(char *buf
, size_t len
, struct dgram_packet
*dgram
)
854 unsigned char *ubuf
= (unsigned char *)buf
;
857 /* put in the header */
859 ubuf
[0] = dgram
->header
.msg_type
;
860 ubuf
[1] = (((int)dgram
->header
.flags
.node_type
)<<2);
861 if (dgram
->header
.flags
.more
)
863 if (dgram
->header
.flags
.first
)
865 RSSVAL(ubuf
,2,dgram
->header
.dgm_id
);
866 putip(ubuf
+4,(char *)&dgram
->header
.source_ip
);
867 RSSVAL(ubuf
,8,dgram
->header
.source_port
);
868 RSSVAL(ubuf
,12,dgram
->header
.packet_offset
);
873 if (dgram
->header
.msg_type
== 0x10 ||
874 dgram
->header
.msg_type
== 0x11 ||
875 dgram
->header
.msg_type
== 0x12) {
876 offset
+= put_nmb_name((char *)ubuf
,offset
,&dgram
->source_name
);
877 offset
+= put_nmb_name((char *)ubuf
,offset
,&dgram
->dest_name
);
881 memcpy(ubuf
+offset
,dgram
->data
,dgram
->datasize
);
883 offset
+= dgram
->datasize
;
885 /* automatically set the dgm_length
886 * NOTE: RFC1002 says the dgm_length does *not*
887 * include the fourteen-byte header. crh
889 dgram
->header
.dgm_length
= (offset
- 14);
891 RSSVAL(ubuf
,10,dgram
->header
.dgm_length
);
897 /*******************************************************************
899 *******************************************************************/
901 void make_nmb_name( struct nmb_name
*n
, const char *name
, int type
)
904 memset( (char *)n
, '\0', sizeof(struct nmb_name
) );
905 fstrcpy(unix_name
, name
);
906 strupper_m(unix_name
);
907 push_ascii(n
->name
, unix_name
, sizeof(n
->name
), STR_TERMINATE
);
908 n
->name_type
= (unsigned int)type
& 0xFF;
909 push_ascii(n
->scope
, global_scope(), 64, STR_TERMINATE
);
912 /*******************************************************************
913 Compare two nmb names
914 ******************************************************************/
916 bool nmb_name_equal(struct nmb_name
*n1
, struct nmb_name
*n2
)
918 return ((n1
->name_type
== n2
->name_type
) &&
919 strequal(n1
->name
,n2
->name
) &&
920 strequal(n1
->scope
,n2
->scope
));
923 /*******************************************************************
924 Build a nmb packet ready for sending.
925 If buf == NULL this is a length calculation.
926 ******************************************************************/
928 static int build_nmb(char *buf
, size_t len
, struct nmb_packet
*nmb
)
930 unsigned char *ubuf
= (unsigned char *)buf
;
933 if (len
&& len
< 12) {
937 /* put in the header */
939 RSSVAL(ubuf
,offset
,nmb
->header
.name_trn_id
);
940 ubuf
[offset
+2] = (nmb
->header
.opcode
& 0xF) << 3;
941 if (nmb
->header
.response
)
942 ubuf
[offset
+2] |= (1<<7);
943 if (nmb
->header
.nm_flags
.authoritative
&&
944 nmb
->header
.response
)
945 ubuf
[offset
+2] |= 0x4;
946 if (nmb
->header
.nm_flags
.trunc
)
947 ubuf
[offset
+2] |= 0x2;
948 if (nmb
->header
.nm_flags
.recursion_desired
)
949 ubuf
[offset
+2] |= 0x1;
950 if (nmb
->header
.nm_flags
.recursion_available
&&
951 nmb
->header
.response
)
952 ubuf
[offset
+3] |= 0x80;
953 if (nmb
->header
.nm_flags
.bcast
)
954 ubuf
[offset
+3] |= 0x10;
955 ubuf
[offset
+3] |= (nmb
->header
.rcode
& 0xF);
957 RSSVAL(ubuf
,offset
+4,nmb
->header
.qdcount
);
958 RSSVAL(ubuf
,offset
+6,nmb
->header
.ancount
);
959 RSSVAL(ubuf
,offset
+8,nmb
->header
.nscount
);
960 RSSVAL(ubuf
,offset
+10,nmb
->header
.arcount
);
964 if (nmb
->header
.qdcount
) {
965 /* XXXX this doesn't handle a qdcount of > 1 */
968 int extra
= put_nmb_name(NULL
,offset
,
969 &nmb
->question
.question_name
);
970 if (offset
+ extra
> len
) {
974 offset
+= put_nmb_name((char *)ubuf
,offset
,
975 &nmb
->question
.question_name
);
977 RSSVAL(ubuf
,offset
,nmb
->question
.question_type
);
978 RSSVAL(ubuf
,offset
+2,nmb
->question
.question_class
);
983 if (nmb
->header
.ancount
) {
986 int extra
= put_res_rec(NULL
,offset
,nmb
->answers
,
987 nmb
->header
.ancount
);
988 if (offset
+ extra
> len
) {
992 offset
+= put_res_rec((char *)ubuf
,offset
,nmb
->answers
,
993 nmb
->header
.ancount
);
996 if (nmb
->header
.nscount
) {
999 int extra
= put_res_rec(NULL
,offset
,nmb
->nsrecs
,
1000 nmb
->header
.nscount
);
1001 if (offset
+ extra
> len
) {
1005 offset
+= put_res_rec((char *)ubuf
,offset
,nmb
->nsrecs
,
1006 nmb
->header
.nscount
);
1010 * The spec says we must put compressed name pointers
1011 * in the following outgoing packets :
1012 * NAME_REGISTRATION_REQUEST, NAME_REFRESH_REQUEST,
1013 * NAME_RELEASE_REQUEST.
1016 if((nmb
->header
.response
== False
) &&
1017 ((nmb
->header
.opcode
== NMB_NAME_REG_OPCODE
) ||
1018 (nmb
->header
.opcode
== NMB_NAME_RELEASE_OPCODE
) ||
1019 (nmb
->header
.opcode
== NMB_NAME_REFRESH_OPCODE_8
) ||
1020 (nmb
->header
.opcode
== NMB_NAME_REFRESH_OPCODE_9
) ||
1021 (nmb
->header
.opcode
== NMB_NAME_MULTIHOMED_REG_OPCODE
)) &&
1022 (nmb
->header
.arcount
== 1)) {
1026 int extra
= put_compressed_name_ptr(NULL
,offset
,
1027 nmb
->additional
,12);
1028 if (offset
+ extra
> len
) {
1032 offset
+= put_compressed_name_ptr(ubuf
,offset
,
1033 nmb
->additional
,12);
1034 } else if (nmb
->header
.arcount
) {
1037 int extra
= put_res_rec(NULL
,offset
,nmb
->additional
,
1038 nmb
->header
.arcount
);
1039 if (offset
+ extra
> len
) {
1043 offset
+= put_res_rec((char *)ubuf
,offset
,nmb
->additional
,
1044 nmb
->header
.arcount
);
1049 /*******************************************************************
1051 ******************************************************************/
1053 int build_packet(char *buf
, size_t buflen
, struct packet_struct
*p
)
1057 switch (p
->packet_type
) {
1059 len
= build_nmb(buf
,buflen
,&p
->packet
.nmb
);
1063 len
= build_dgram(buf
,buflen
,&p
->packet
.dgram
);
1070 /*******************************************************************
1071 Send a packet_struct.
1072 ******************************************************************/
1074 bool send_packet(struct packet_struct
*p
)
1079 memset(buf
,'\0',sizeof(buf
));
1081 len
= build_packet(buf
, sizeof(buf
), p
);
1086 return(send_udp(p
->fd
,buf
,len
,p
->ip
,p
->port
));
1089 /****************************************************************************
1090 Receive a packet with timeout on a open UDP filedescriptor.
1091 The timeout is in milliseconds
1092 ***************************************************************************/
1094 struct packet_struct
*receive_packet(int fd
,enum packet_type type
,int t
)
1097 struct timeval timeout
;
1102 timeout
.tv_sec
= t
/1000;
1103 timeout
.tv_usec
= 1000*(t
%1000);
1105 if ((ret
= sys_select_intr(fd
+1,&fds
,NULL
,NULL
,&timeout
)) == -1) {
1106 /* errno should be EBADF or EINVAL. */
1107 DEBUG(0,("select returned -1, errno = %s (%d)\n",
1108 strerror(errno
), errno
));
1112 if (ret
== 0) /* timeout */
1115 if (FD_ISSET(fd
,&fds
))
1116 return(read_packet(fd
,type
));
1121 /****************************************************************************
1122 Receive a UDP/137 packet either via UDP or from the unexpected packet
1123 queue. The packet must be a reply packet and have the specified trn_id.
1124 The timeout is in milliseconds.
1125 ***************************************************************************/
1127 struct packet_struct
*receive_nmb_packet(int fd
, int t
, int trn_id
)
1129 struct packet_struct
*p
;
1131 p
= receive_packet(fd
, NMB_PACKET
, t
);
1133 if (p
&& p
->packet
.nmb
.header
.response
&&
1134 p
->packet
.nmb
.header
.name_trn_id
== trn_id
) {
1140 /* try the unexpected packet queue */
1141 return receive_unexpected(NMB_PACKET
, trn_id
, NULL
);
1144 /****************************************************************************
1145 Receive a UDP/138 packet either via UDP or from the unexpected packet
1146 queue. The packet must be a reply packet and have the specified mailslot name
1147 The timeout is in milliseconds.
1148 ***************************************************************************/
1150 struct packet_struct
*receive_dgram_packet(int fd
, int t
,
1151 const char *mailslot_name
)
1153 struct packet_struct
*p
;
1155 p
= receive_packet(fd
, DGRAM_PACKET
, t
);
1157 if (p
&& match_mailslot_name(p
, mailslot_name
)) {
1163 /* try the unexpected packet queue */
1164 return receive_unexpected(DGRAM_PACKET
, 0, mailslot_name
);
1167 /****************************************************************************
1168 See if a datagram has the right mailslot name.
1169 ***************************************************************************/
1171 bool match_mailslot_name(struct packet_struct
*p
, const char *mailslot_name
)
1173 struct dgram_packet
*dgram
= &p
->packet
.dgram
;
1176 buf
= &dgram
->data
[0];
1181 if (memcmp(buf
, mailslot_name
, strlen(mailslot_name
)+1) == 0) {
1188 /****************************************************************************
1189 Return the number of bits that match between two len character buffers
1190 ***************************************************************************/
1192 int matching_len_bits(unsigned char *p1
, unsigned char *p2
, size_t len
)
1196 for (i
=0; i
<len
; i
++) {
1205 for (j
=0; j
<8; j
++) {
1206 if ((p1
[i
] & (1<<(7-j
))) != (p2
[i
] & (1<<(7-j
))))
1214 static unsigned char sort_ip
[4];
1216 /****************************************************************************
1217 Compare two query reply records.
1218 ***************************************************************************/
1220 static int name_query_comp(unsigned char *p1
, unsigned char *p2
)
1222 return matching_len_bits(p2
+2, sort_ip
, 4) -
1223 matching_len_bits(p1
+2, sort_ip
, 4);
1226 /****************************************************************************
1227 Sort a set of 6 byte name query response records so that the IPs that
1228 have the most leading bits in common with the specified address come first.
1229 ***************************************************************************/
1231 void sort_query_replies(char *data
, int n
, struct in_addr ip
)
1236 putip(sort_ip
, (char *)&ip
);
1238 qsort(data
, n
, 6, QSORT_CAST name_query_comp
);
1241 /****************************************************************************
1242 Interpret the weird netbios "name" into a unix fstring. Return the name type.
1243 ****************************************************************************/
1245 static int name_interpret(char *in
, fstring name
)
1248 int len
= (*in
++) / 2;
1250 char *out
= out_string
;
1254 if (len
> 30 || len
<1)
1258 if (in
[0] < 'A' || in
[0] > 'P' || in
[1] < 'A' || in
[1] > 'P') {
1262 *out
= ((in
[0]-'A')<<4) + (in
[1]-'A');
1269 #ifdef NETBIOS_SCOPE
1270 /* Handle any scope names */
1272 *out
++ = '.'; /* Scope names are separated by periods */
1273 len
= *(unsigned char *)in
++;
1274 StrnCpy(out
, in
, len
);
1280 pull_ascii_fstring(name
, out_string
);
1285 /****************************************************************************
1286 Mangle a name into netbios format.
1287 Note: <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
1288 ****************************************************************************/
1290 int name_mangle( char *In
, char *Out
, char name_type
)
1297 /* Safely copy the input string, In, into buf[]. */
1298 if (strcmp(In
,"*") == 0)
1299 put_name(buf
, "*", '\0', 0x00);
1301 /* We use an fstring here as mb dos names can expend x3 when
1306 pull_ascii_fstring(buf_unix
, In
);
1307 strupper_m(buf_unix
);
1309 push_ascii_nstring(buf_dos
, buf_unix
);
1310 put_name(buf
, buf_dos
, ' ', name_type
);
1313 /* Place the length of the first field into the output buffer. */
1317 /* Now convert the name to the rfc1001/1002 format. */
1318 for( i
= 0; i
< MAX_NETBIOSNAME_LEN
; i
++ ) {
1319 p
[i
*2] = ( (buf
[i
] >> 4) & 0x000F ) + 'A';
1320 p
[(i
*2)+1] = (buf
[i
] & 0x000F) + 'A';
1325 /* Add the scope string. */
1326 for( i
= 0, len
= 0; *(global_scope()) != '\0'; i
++, len
++ ) {
1327 switch( (global_scope())[i
] ) {
1332 return( name_len(Out
) );
1339 p
[len
+1] = (global_scope())[i
];
1344 return( name_len(Out
) );
1347 /****************************************************************************
1348 Find a pointer to a netbios name.
1349 ****************************************************************************/
1351 static char *name_ptr(char *buf
,int ofs
)
1353 unsigned char c
= *(unsigned char *)(buf
+ofs
);
1355 if ((c
& 0xC0) == 0xC0) {
1356 uint16 l
= RSVAL(buf
, ofs
) & 0x3FFF;
1357 DEBUG(5,("name ptr to pos %d from %d is %s\n",l
,ofs
,buf
+l
));
1364 /****************************************************************************
1365 Extract a netbios name from a buf (into a unix string) return name type.
1366 ****************************************************************************/
1368 int name_extract(char *buf
,int ofs
, fstring name
)
1370 char *p
= name_ptr(buf
,ofs
);
1371 int d
= PTR_DIFF(p
,buf
+ofs
);
1374 if (d
< -50 || d
> 50)
1376 return(name_interpret(p
,name
));
1379 /****************************************************************************
1380 Return the total storage length of a mangled name.
1381 ****************************************************************************/
1383 int name_len(char *s1
)
1385 /* NOTE: this argument _must_ be unsigned */
1386 unsigned char *s
= (unsigned char *)s1
;
1389 /* If the two high bits of the byte are set, return 2. */
1390 if (0xC0 == (*s
& 0xC0))
1393 /* Add up the length bytes. */
1394 for (len
= 1; (*s
); s
+= (*s
) + 1) {
1396 SMB_ASSERT(len
< 80);