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 packet_struct
*p
)
854 struct dgram_packet
*dgram
= &p
->packet
.dgram
;
855 unsigned char *ubuf
= (unsigned char *)buf
;
858 /* put in the header */
860 ubuf
[0] = dgram
->header
.msg_type
;
861 ubuf
[1] = (((int)dgram
->header
.flags
.node_type
)<<2);
862 if (dgram
->header
.flags
.more
)
864 if (dgram
->header
.flags
.first
)
866 RSSVAL(ubuf
,2,dgram
->header
.dgm_id
);
867 putip(ubuf
+4,(char *)&dgram
->header
.source_ip
);
868 RSSVAL(ubuf
,8,dgram
->header
.source_port
);
869 RSSVAL(ubuf
,12,dgram
->header
.packet_offset
);
874 if (dgram
->header
.msg_type
== 0x10 ||
875 dgram
->header
.msg_type
== 0x11 ||
876 dgram
->header
.msg_type
== 0x12) {
877 offset
+= put_nmb_name((char *)ubuf
,offset
,&dgram
->source_name
);
878 offset
+= put_nmb_name((char *)ubuf
,offset
,&dgram
->dest_name
);
882 memcpy(ubuf
+offset
,dgram
->data
,dgram
->datasize
);
884 offset
+= dgram
->datasize
;
886 /* automatically set the dgm_length
887 * NOTE: RFC1002 says the dgm_length does *not*
888 * include the fourteen-byte header. crh
890 dgram
->header
.dgm_length
= (offset
- 14);
892 RSSVAL(ubuf
,10,dgram
->header
.dgm_length
);
898 /*******************************************************************
900 *******************************************************************/
902 void make_nmb_name( struct nmb_name
*n
, const char *name
, int type
)
905 memset( (char *)n
, '\0', sizeof(struct nmb_name
) );
906 fstrcpy(unix_name
, name
);
907 strupper_m(unix_name
);
908 push_ascii(n
->name
, unix_name
, sizeof(n
->name
), STR_TERMINATE
);
909 n
->name_type
= (unsigned int)type
& 0xFF;
910 push_ascii(n
->scope
, global_scope(), 64, STR_TERMINATE
);
913 /*******************************************************************
914 Compare two nmb names
915 ******************************************************************/
917 bool nmb_name_equal(struct nmb_name
*n1
, struct nmb_name
*n2
)
919 return ((n1
->name_type
== n2
->name_type
) &&
920 strequal(n1
->name
,n2
->name
) &&
921 strequal(n1
->scope
,n2
->scope
));
924 /*******************************************************************
925 Build a nmb packet ready for sending.
926 If buf == NULL this is a length calculation.
927 ******************************************************************/
929 static int build_nmb(char *buf
, size_t len
, struct packet_struct
*p
)
931 struct nmb_packet
*nmb
= &p
->packet
.nmb
;
932 unsigned char *ubuf
= (unsigned char *)buf
;
935 if (len
&& len
< 12) {
939 /* put in the header */
941 RSSVAL(ubuf
,offset
,nmb
->header
.name_trn_id
);
942 ubuf
[offset
+2] = (nmb
->header
.opcode
& 0xF) << 3;
943 if (nmb
->header
.response
)
944 ubuf
[offset
+2] |= (1<<7);
945 if (nmb
->header
.nm_flags
.authoritative
&&
946 nmb
->header
.response
)
947 ubuf
[offset
+2] |= 0x4;
948 if (nmb
->header
.nm_flags
.trunc
)
949 ubuf
[offset
+2] |= 0x2;
950 if (nmb
->header
.nm_flags
.recursion_desired
)
951 ubuf
[offset
+2] |= 0x1;
952 if (nmb
->header
.nm_flags
.recursion_available
&&
953 nmb
->header
.response
)
954 ubuf
[offset
+3] |= 0x80;
955 if (nmb
->header
.nm_flags
.bcast
)
956 ubuf
[offset
+3] |= 0x10;
957 ubuf
[offset
+3] |= (nmb
->header
.rcode
& 0xF);
959 RSSVAL(ubuf
,offset
+4,nmb
->header
.qdcount
);
960 RSSVAL(ubuf
,offset
+6,nmb
->header
.ancount
);
961 RSSVAL(ubuf
,offset
+8,nmb
->header
.nscount
);
962 RSSVAL(ubuf
,offset
+10,nmb
->header
.arcount
);
966 if (nmb
->header
.qdcount
) {
967 /* XXXX this doesn't handle a qdcount of > 1 */
970 int extra
= put_nmb_name(NULL
,offset
,
971 &nmb
->question
.question_name
);
972 if (offset
+ extra
> len
) {
976 offset
+= put_nmb_name((char *)ubuf
,offset
,
977 &nmb
->question
.question_name
);
979 RSSVAL(ubuf
,offset
,nmb
->question
.question_type
);
980 RSSVAL(ubuf
,offset
+2,nmb
->question
.question_class
);
985 if (nmb
->header
.ancount
) {
988 int extra
= put_res_rec(NULL
,offset
,nmb
->answers
,
989 nmb
->header
.ancount
);
990 if (offset
+ extra
> len
) {
994 offset
+= put_res_rec((char *)ubuf
,offset
,nmb
->answers
,
995 nmb
->header
.ancount
);
998 if (nmb
->header
.nscount
) {
1001 int extra
= put_res_rec(NULL
,offset
,nmb
->nsrecs
,
1002 nmb
->header
.nscount
);
1003 if (offset
+ extra
> len
) {
1007 offset
+= put_res_rec((char *)ubuf
,offset
,nmb
->nsrecs
,
1008 nmb
->header
.nscount
);
1012 * The spec says we must put compressed name pointers
1013 * in the following outgoing packets :
1014 * NAME_REGISTRATION_REQUEST, NAME_REFRESH_REQUEST,
1015 * NAME_RELEASE_REQUEST.
1018 if((nmb
->header
.response
== False
) &&
1019 ((nmb
->header
.opcode
== NMB_NAME_REG_OPCODE
) ||
1020 (nmb
->header
.opcode
== NMB_NAME_RELEASE_OPCODE
) ||
1021 (nmb
->header
.opcode
== NMB_NAME_REFRESH_OPCODE_8
) ||
1022 (nmb
->header
.opcode
== NMB_NAME_REFRESH_OPCODE_9
) ||
1023 (nmb
->header
.opcode
== NMB_NAME_MULTIHOMED_REG_OPCODE
)) &&
1024 (nmb
->header
.arcount
== 1)) {
1028 int extra
= put_compressed_name_ptr(NULL
,offset
,
1029 nmb
->additional
,12);
1030 if (offset
+ extra
> len
) {
1034 offset
+= put_compressed_name_ptr(ubuf
,offset
,
1035 nmb
->additional
,12);
1036 } else if (nmb
->header
.arcount
) {
1039 int extra
= put_res_rec(NULL
,offset
,nmb
->additional
,
1040 nmb
->header
.arcount
);
1041 if (offset
+ extra
> len
) {
1045 offset
+= put_res_rec((char *)ubuf
,offset
,nmb
->additional
,
1046 nmb
->header
.arcount
);
1051 /*******************************************************************
1053 ******************************************************************/
1055 int build_packet(char *buf
, size_t buflen
, struct packet_struct
*p
)
1059 switch (p
->packet_type
) {
1061 len
= build_nmb(buf
,buflen
,p
);
1065 len
= build_dgram(buf
,buflen
,p
);
1072 /*******************************************************************
1073 Send a packet_struct.
1074 ******************************************************************/
1076 bool send_packet(struct packet_struct
*p
)
1081 memset(buf
,'\0',sizeof(buf
));
1083 len
= build_packet(buf
, sizeof(buf
), p
);
1088 return(send_udp(p
->fd
,buf
,len
,p
->ip
,p
->port
));
1091 /****************************************************************************
1092 Receive a packet with timeout on a open UDP filedescriptor.
1093 The timeout is in milliseconds
1094 ***************************************************************************/
1096 struct packet_struct
*receive_packet(int fd
,enum packet_type type
,int t
)
1099 struct timeval timeout
;
1104 timeout
.tv_sec
= t
/1000;
1105 timeout
.tv_usec
= 1000*(t
%1000);
1107 if ((ret
= sys_select_intr(fd
+1,&fds
,NULL
,NULL
,&timeout
)) == -1) {
1108 /* errno should be EBADF or EINVAL. */
1109 DEBUG(0,("select returned -1, errno = %s (%d)\n",
1110 strerror(errno
), errno
));
1114 if (ret
== 0) /* timeout */
1117 if (FD_ISSET(fd
,&fds
))
1118 return(read_packet(fd
,type
));
1123 /****************************************************************************
1124 Receive a UDP/137 packet either via UDP or from the unexpected packet
1125 queue. The packet must be a reply packet and have the specified trn_id.
1126 The timeout is in milliseconds.
1127 ***************************************************************************/
1129 struct packet_struct
*receive_nmb_packet(int fd
, int t
, int trn_id
)
1131 struct packet_struct
*p
;
1133 p
= receive_packet(fd
, NMB_PACKET
, t
);
1135 if (p
&& p
->packet
.nmb
.header
.response
&&
1136 p
->packet
.nmb
.header
.name_trn_id
== trn_id
) {
1142 /* try the unexpected packet queue */
1143 return receive_unexpected(NMB_PACKET
, trn_id
, NULL
);
1146 /****************************************************************************
1147 Receive a UDP/138 packet either via UDP or from the unexpected packet
1148 queue. The packet must be a reply packet and have the specified mailslot name
1149 The timeout is in milliseconds.
1150 ***************************************************************************/
1152 struct packet_struct
*receive_dgram_packet(int fd
, int t
,
1153 const char *mailslot_name
)
1155 struct packet_struct
*p
;
1157 p
= receive_packet(fd
, DGRAM_PACKET
, t
);
1159 if (p
&& match_mailslot_name(p
, mailslot_name
)) {
1165 /* try the unexpected packet queue */
1166 return receive_unexpected(DGRAM_PACKET
, 0, mailslot_name
);
1169 /****************************************************************************
1170 See if a datagram has the right mailslot name.
1171 ***************************************************************************/
1173 bool match_mailslot_name(struct packet_struct
*p
, const char *mailslot_name
)
1175 struct dgram_packet
*dgram
= &p
->packet
.dgram
;
1178 buf
= &dgram
->data
[0];
1183 if (memcmp(buf
, mailslot_name
, strlen(mailslot_name
)+1) == 0) {
1190 /****************************************************************************
1191 Return the number of bits that match between two len character buffers
1192 ***************************************************************************/
1194 int matching_len_bits(unsigned char *p1
, unsigned char *p2
, size_t len
)
1198 for (i
=0; i
<len
; i
++) {
1207 for (j
=0; j
<8; j
++) {
1208 if ((p1
[i
] & (1<<(7-j
))) != (p2
[i
] & (1<<(7-j
))))
1216 static unsigned char sort_ip
[4];
1218 /****************************************************************************
1219 Compare two query reply records.
1220 ***************************************************************************/
1222 static int name_query_comp(unsigned char *p1
, unsigned char *p2
)
1224 return matching_len_bits(p2
+2, sort_ip
, 4) -
1225 matching_len_bits(p1
+2, sort_ip
, 4);
1228 /****************************************************************************
1229 Sort a set of 6 byte name query response records so that the IPs that
1230 have the most leading bits in common with the specified address come first.
1231 ***************************************************************************/
1233 void sort_query_replies(char *data
, int n
, struct in_addr ip
)
1238 putip(sort_ip
, (char *)&ip
);
1240 qsort(data
, n
, 6, QSORT_CAST name_query_comp
);
1243 /****************************************************************************
1244 Interpret the weird netbios "name" into a unix fstring. Return the name type.
1245 ****************************************************************************/
1247 static int name_interpret(char *in
, fstring name
)
1250 int len
= (*in
++) / 2;
1252 char *out
= out_string
;
1256 if (len
> 30 || len
<1)
1260 if (in
[0] < 'A' || in
[0] > 'P' || in
[1] < 'A' || in
[1] > 'P') {
1264 *out
= ((in
[0]-'A')<<4) + (in
[1]-'A');
1271 #ifdef NETBIOS_SCOPE
1272 /* Handle any scope names */
1274 *out
++ = '.'; /* Scope names are separated by periods */
1275 len
= *(unsigned char *)in
++;
1276 StrnCpy(out
, in
, len
);
1282 pull_ascii_fstring(name
, out_string
);
1287 /****************************************************************************
1288 Mangle a name into netbios format.
1289 Note: <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
1290 ****************************************************************************/
1292 int name_mangle( char *In
, char *Out
, char name_type
)
1299 /* Safely copy the input string, In, into buf[]. */
1300 if (strcmp(In
,"*") == 0)
1301 put_name(buf
, "*", '\0', 0x00);
1303 /* We use an fstring here as mb dos names can expend x3 when
1308 pull_ascii_fstring(buf_unix
, In
);
1309 strupper_m(buf_unix
);
1311 push_ascii_nstring(buf_dos
, buf_unix
);
1312 put_name(buf
, buf_dos
, ' ', name_type
);
1315 /* Place the length of the first field into the output buffer. */
1319 /* Now convert the name to the rfc1001/1002 format. */
1320 for( i
= 0; i
< MAX_NETBIOSNAME_LEN
; i
++ ) {
1321 p
[i
*2] = ( (buf
[i
] >> 4) & 0x000F ) + 'A';
1322 p
[(i
*2)+1] = (buf
[i
] & 0x000F) + 'A';
1327 /* Add the scope string. */
1328 for( i
= 0, len
= 0; *(global_scope()) != '\0'; i
++, len
++ ) {
1329 switch( (global_scope())[i
] ) {
1334 return( name_len(Out
) );
1341 p
[len
+1] = (global_scope())[i
];
1346 return( name_len(Out
) );
1349 /****************************************************************************
1350 Find a pointer to a netbios name.
1351 ****************************************************************************/
1353 static char *name_ptr(char *buf
,int ofs
)
1355 unsigned char c
= *(unsigned char *)(buf
+ofs
);
1357 if ((c
& 0xC0) == 0xC0) {
1358 uint16 l
= RSVAL(buf
, ofs
) & 0x3FFF;
1359 DEBUG(5,("name ptr to pos %d from %d is %s\n",l
,ofs
,buf
+l
));
1366 /****************************************************************************
1367 Extract a netbios name from a buf (into a unix string) return name type.
1368 ****************************************************************************/
1370 int name_extract(char *buf
,int ofs
, fstring name
)
1372 char *p
= name_ptr(buf
,ofs
);
1373 int d
= PTR_DIFF(p
,buf
+ofs
);
1376 if (d
< -50 || d
> 50)
1378 return(name_interpret(p
,name
));
1381 /****************************************************************************
1382 Return the total storage length of a mangled name.
1383 ****************************************************************************/
1385 int name_len(char *s1
)
1387 /* NOTE: this argument _must_ be unsigned */
1388 unsigned char *s
= (unsigned char *)s1
;
1391 /* If the two high bits of the byte are set, return 2. */
1392 if (0xC0 == (*s
& 0xC0))
1395 /* Add up the length bytes. */
1396 for (len
= 1; (*s
); s
+= (*s
) + 1) {
1398 SMB_ASSERT(len
< 80);