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) {
75 for (i
= 0; i
< res
->rdlength
; i
+= MAX_NETBIOSNAME_LEN
) {
76 DEBUGADD(4, (" %s %3x char ", hdr
, i
));
78 for (j
= 0; j
< MAX_NETBIOSNAME_LEN
; j
++) {
79 unsigned char x
= res
->rdata
[i
+j
];
80 if (x
< 32 || x
> 127)
83 if (i
+j
>= res
->rdlength
)
85 DEBUGADD(4, ("%c", x
));
88 DEBUGADD(4, (" hex "));
90 for (j
= 0; j
< MAX_NETBIOSNAME_LEN
; j
++) {
91 if (i
+j
>= res
->rdlength
)
93 DEBUGADD(4, ("%02X", (unsigned char)res
->rdata
[i
+j
]));
100 /****************************************************************************
101 Process a nmb packet.
102 ****************************************************************************/
104 void debug_nmb_packet(struct packet_struct
*p
)
106 struct nmb_packet
*nmb
= &p
->packet
.nmb
;
108 if( DEBUGLVL( 4 ) ) {
109 dbgtext( "nmb packet from %s(%d) header: id=%d "
110 "opcode=%s(%d) response=%s\n",
111 inet_ntoa(p
->ip
), p
->port
,
112 nmb
->header
.name_trn_id
,
113 lookup_opcode_name(nmb
->header
.opcode
),
115 BOOLSTR(nmb
->header
.response
) );
116 dbgtext( " header: flags: bcast=%s rec_avail=%s "
117 "rec_des=%s trunc=%s auth=%s\n",
118 BOOLSTR(nmb
->header
.nm_flags
.bcast
),
119 BOOLSTR(nmb
->header
.nm_flags
.recursion_available
),
120 BOOLSTR(nmb
->header
.nm_flags
.recursion_desired
),
121 BOOLSTR(nmb
->header
.nm_flags
.trunc
),
122 BOOLSTR(nmb
->header
.nm_flags
.authoritative
) );
123 dbgtext( " header: rcode=%d qdcount=%d ancount=%d "
124 "nscount=%d arcount=%d\n",
129 nmb
->header
.arcount
);
132 if (nmb
->header
.qdcount
) {
133 DEBUGADD( 4, ( " question: q_name=%s q_type=%d q_class=%d\n",
134 nmb_namestr(&nmb
->question
.question_name
),
135 nmb
->question
.question_type
,
136 nmb
->question
.question_class
) );
139 if (nmb
->answers
&& nmb
->header
.ancount
) {
140 debug_nmb_res_rec(nmb
->answers
,"answers");
142 if (nmb
->nsrecs
&& nmb
->header
.nscount
) {
143 debug_nmb_res_rec(nmb
->nsrecs
,"nsrecs");
145 if (nmb
->additional
&& nmb
->header
.arcount
) {
146 debug_nmb_res_rec(nmb
->additional
,"additional");
150 /*******************************************************************
151 Handle "compressed" name pointers.
152 ******************************************************************/
154 static bool handle_name_ptrs(unsigned char *ubuf
,int *offset
,int length
,
155 bool *got_pointer
,int *ret
)
159 while ((ubuf
[*offset
] & 0xC0) == 0xC0) {
163 if (*offset
> length
- 2) {
166 (*offset
) = ((ubuf
[*offset
] & ~0xC0)<<8) | ubuf
[(*offset
)+1];
167 if (loop_count
++ == 10 ||
168 (*offset
) < 0 || (*offset
)>(length
-2)) {
175 /*******************************************************************
176 Parse a nmb name from "compressed" format to something readable
177 return the space taken by the name, or 0 if the name is invalid
178 ******************************************************************/
180 static int parse_nmb_name(char *inbuf
,int ofs
,int length
, struct nmb_name
*name
)
183 unsigned char *ubuf
= (unsigned char *)inbuf
;
185 bool got_pointer
=False
;
189 if (length
- offset
< 2)
192 /* handle initial name pointers */
193 if (!handle_name_ptrs(ubuf
,&offset
,length
,&got_pointer
,&ret
))
198 /* m must be 32 to exactly fill in the 16 bytes of the netbios name */
202 /* Cannot go past length. */
203 if (offset
+m
+2 > length
) {
207 memset((char *)name
,'\0',sizeof(*name
));
209 /* the "compressed" part */
215 c1
= ubuf
[offset
++]-'A';
216 c2
= ubuf
[offset
++]-'A';
217 if ((c1
& 0xF0) || (c2
& 0xF0)) {
220 if (n
>= sizeof(name
->name
)) {
223 name
->name
[n
++] = (c1
<<4) | c2
;
227 * RFC1002: For a valid NetBIOS name, exiting from the above,
228 * n *must* be MAX_NETBIOSNAME_LEN (16).
230 if (n
!= MAX_NETBIOSNAME_LEN
) {
234 /* parse out the name type, its always
235 * in the 16th byte of the name */
236 name
->name_type
= ((unsigned char)name
->name
[15]) & 0xff;
238 /* remove trailing spaces */
241 while (n
&& name
->name
[n
]==' ')
244 /* now the domain parts (if any) */
246 while (ubuf
[offset
]) {
247 /* we can have pointers within the domain part as well */
248 if (!handle_name_ptrs(ubuf
,&offset
,length
,&got_pointer
,&ret
))
253 * Don't allow null domain parts.
260 name
->scope
[n
++] = '.';
261 if (m
+2+offset
>length
|| n
+m
+1>sizeof(name
->scope
))
265 name
->scope
[n
++] = (char)ubuf
[offset
++];
268 * Watch for malicious loops.
270 if (loop_count
++ == 10)
273 name
->scope
[n
++] = 0;
278 /****************************************************************************
279 Put a netbios name, padding(s) and a name type into a 16 character buffer.
280 name is already in DOS charset.
281 [15 bytes name + padding][1 byte name type].
282 ****************************************************************************/
284 void put_name(char *dest
, const char *name
, int pad
, unsigned int name_type
)
286 size_t len
= strlen(name
);
288 memcpy(dest
, name
, (len
< MAX_NETBIOSNAME_LEN
) ?
289 len
: MAX_NETBIOSNAME_LEN
- 1);
290 if (len
< MAX_NETBIOSNAME_LEN
- 1) {
291 memset(dest
+ len
, pad
, MAX_NETBIOSNAME_LEN
- 1 - len
);
293 dest
[MAX_NETBIOSNAME_LEN
- 1] = name_type
;
296 /*******************************************************************
297 Put a compressed nmb name into a buffer. Return the length of the
300 Compressed names are really weird. The "compression" doubles the
301 size. The idea is that it also means that compressed names conform
302 to the doman name system. See RFC1002.
304 If buf == NULL this is a length calculation.
305 ******************************************************************/
307 static int put_nmb_name(char *buf
, size_t buflen
, int offset
,struct nmb_name
*name
)
313 if (strcmp(name
->name
,"*") == 0) {
314 /* special case for wildcard name */
315 put_name(buf1
, "*", '\0', name
->name_type
);
317 put_name(buf1
, name
->name
, ' ', name
->name_type
);
321 if (offset
>= buflen
) {
329 for (m
=0;m
<MAX_NETBIOSNAME_LEN
;m
++) {
331 if (offset
+2+2*m
>= buflen
) {
334 buf
[offset
+1+2*m
] = 'A' + ((buf1
[m
]>>4)&0xF);
335 buf
[offset
+2+2*m
] = 'A' + (buf1
[m
]&0xF);
341 if (offset
>= buflen
) {
347 if (name
->scope
[0]) {
348 /* XXXX this scope handling needs testing */
349 size_t scopenamelen
= strlen(name
->scope
) + 1;
352 if (offset
+1+scopenamelen
>= buflen
) {
355 strlcpy(&buf
[offset
+1],name
->scope
,
356 buflen
- (offset
+1));
359 while ((p
= strchr_m(p
,'.'))) {
360 buf
[offset
] = PTR_DIFF(p
,&buf
[offset
+1]);
361 offset
+= (buf
[offset
] + 1);
362 if (offset
+1 >= buflen
) {
367 buf
[offset
] = strlen(&buf
[offset
+1]);
374 /*******************************************************************
375 Useful for debugging messages.
376 ******************************************************************/
378 char *nmb_namestr(const struct nmb_name
*n
)
383 pull_ascii_fstring(name
, n
->name
);
385 result
= talloc_asprintf(talloc_tos(), "%s<%02x>", name
,
388 result
= talloc_asprintf(talloc_tos(), "%s<%02x>.%s", name
,
389 n
->name_type
, n
->scope
);
391 SMB_ASSERT(result
!= NULL
);
395 /*******************************************************************
396 Allocate and parse some resource records.
397 ******************************************************************/
399 static bool parse_alloc_res_rec(char *inbuf
,int *offset
,int length
,
400 struct res_rec
**recs
, int count
)
404 *recs
= SMB_MALLOC_ARRAY(struct res_rec
, count
);
408 memset((char *)*recs
,'\0',sizeof(**recs
)*count
);
410 for (i
=0;i
<count
;i
++) {
411 int l
= parse_nmb_name(inbuf
,*offset
,length
,
412 &(*recs
)[i
].rr_name
);
414 if (!l
|| (*offset
)+10 > length
) {
418 (*recs
)[i
].rr_type
= RSVAL(inbuf
,(*offset
));
419 (*recs
)[i
].rr_class
= RSVAL(inbuf
,(*offset
)+2);
420 (*recs
)[i
].ttl
= RIVAL(inbuf
,(*offset
)+4);
421 (*recs
)[i
].rdlength
= RSVAL(inbuf
,(*offset
)+8);
423 if ((*recs
)[i
].rdlength
>sizeof((*recs
)[i
].rdata
) ||
424 (*offset
)+(*recs
)[i
].rdlength
> length
) {
428 memcpy((*recs
)[i
].rdata
,inbuf
+(*offset
),(*recs
)[i
].rdlength
);
429 (*offset
) += (*recs
)[i
].rdlength
;
434 /*******************************************************************
435 Put a resource record into a packet.
436 If buf == NULL this is a length calculation.
437 ******************************************************************/
439 static int put_res_rec(char *buf
, size_t buflen
, int offset
,struct res_rec
*recs
,int count
)
444 for (i
=0;i
<count
;i
++) {
445 int l
= put_nmb_name(buf
,buflen
,offset
,&recs
[i
].rr_name
);
449 RSSVAL(buf
,offset
,recs
[i
].rr_type
);
450 RSSVAL(buf
,offset
+2,recs
[i
].rr_class
);
451 RSIVAL(buf
,offset
+4,recs
[i
].ttl
);
452 RSSVAL(buf
,offset
+8,recs
[i
].rdlength
);
453 memcpy(buf
+offset
+10,recs
[i
].rdata
,recs
[i
].rdlength
);
455 offset
+= 10+recs
[i
].rdlength
;
456 ret
+= 10+recs
[i
].rdlength
;
462 /*******************************************************************
463 Put a compressed name pointer record into a packet.
464 If buf == NULL this is a length calculation.
465 ******************************************************************/
467 static int put_compressed_name_ptr(unsigned char *buf
,
474 buf
[offset
] = (0xC0 | ((ptr_offset
>> 8) & 0xFF));
475 buf
[offset
+1] = (ptr_offset
& 0xFF);
479 RSSVAL(buf
,offset
,rec
->rr_type
);
480 RSSVAL(buf
,offset
+2,rec
->rr_class
);
481 RSIVAL(buf
,offset
+4,rec
->ttl
);
482 RSSVAL(buf
,offset
+8,rec
->rdlength
);
483 memcpy(buf
+offset
+10,rec
->rdata
,rec
->rdlength
);
485 offset
+= 10+rec
->rdlength
;
486 ret
= (offset
- ret
);
491 /*******************************************************************
492 Parse a dgram packet. Return False if the packet can't be parsed
493 or is invalid for some reason, True otherwise.
495 This is documented in section 4.4.1 of RFC1002.
496 ******************************************************************/
498 static bool parse_dgram(char *inbuf
,int length
,struct dgram_packet
*dgram
)
503 memset((char *)dgram
,'\0',sizeof(*dgram
));
508 dgram
->header
.msg_type
= CVAL(inbuf
,0);
509 flags
= CVAL(inbuf
,1);
510 dgram
->header
.flags
.node_type
= (enum node_type
)((flags
>>2)&3);
512 dgram
->header
.flags
.more
= True
;
514 dgram
->header
.flags
.first
= True
;
515 dgram
->header
.dgm_id
= RSVAL(inbuf
,2);
516 putip((char *)&dgram
->header
.source_ip
,inbuf
+4);
517 dgram
->header
.source_port
= RSVAL(inbuf
,8);
518 dgram
->header
.dgm_length
= RSVAL(inbuf
,10);
519 dgram
->header
.packet_offset
= RSVAL(inbuf
,12);
523 if (dgram
->header
.msg_type
== 0x10 ||
524 dgram
->header
.msg_type
== 0x11 ||
525 dgram
->header
.msg_type
== 0x12) {
526 offset
+= parse_nmb_name(inbuf
,offset
,length
,
527 &dgram
->source_name
);
528 offset
+= parse_nmb_name(inbuf
,offset
,length
,
532 if (offset
>= length
|| (length
-offset
> sizeof(dgram
->data
)))
535 dgram
->datasize
= length
-offset
;
536 memcpy(dgram
->data
,inbuf
+offset
,dgram
->datasize
);
538 /* Paranioa. Ensure the last 2 bytes in the dgram buffer are
539 zero. This should be true anyway, just enforce it for
540 paranioa sake. JRA. */
541 SMB_ASSERT(dgram
->datasize
<= (sizeof(dgram
->data
)-2));
542 memset(&dgram
->data
[sizeof(dgram
->data
)-2], '\0', 2);
547 /*******************************************************************
548 Parse a nmb packet. Return False if the packet can't be parsed
549 or is invalid for some reason, True otherwise.
550 ******************************************************************/
552 static bool parse_nmb(char *inbuf
,int length
,struct nmb_packet
*nmb
)
556 memset((char *)nmb
,'\0',sizeof(*nmb
));
561 /* parse the header */
562 nmb
->header
.name_trn_id
= RSVAL(inbuf
,0);
564 DEBUG(10,("parse_nmb: packet id = %d\n", nmb
->header
.name_trn_id
));
566 nmb
->header
.opcode
= (CVAL(inbuf
,2) >> 3) & 0xF;
567 nmb
->header
.response
= ((CVAL(inbuf
,2)>>7)&1)?True
:False
;
568 nm_flags
= ((CVAL(inbuf
,2) & 0x7) << 4) + (CVAL(inbuf
,3)>>4);
569 nmb
->header
.nm_flags
.bcast
= (nm_flags
&1)?True
:False
;
570 nmb
->header
.nm_flags
.recursion_available
= (nm_flags
&8)?True
:False
;
571 nmb
->header
.nm_flags
.recursion_desired
= (nm_flags
&0x10)?True
:False
;
572 nmb
->header
.nm_flags
.trunc
= (nm_flags
&0x20)?True
:False
;
573 nmb
->header
.nm_flags
.authoritative
= (nm_flags
&0x40)?True
:False
;
574 nmb
->header
.rcode
= CVAL(inbuf
,3) & 0xF;
575 nmb
->header
.qdcount
= RSVAL(inbuf
,4);
576 nmb
->header
.ancount
= RSVAL(inbuf
,6);
577 nmb
->header
.nscount
= RSVAL(inbuf
,8);
578 nmb
->header
.arcount
= RSVAL(inbuf
,10);
580 if (nmb
->header
.qdcount
) {
581 offset
= parse_nmb_name(inbuf
,12,length
,
582 &nmb
->question
.question_name
);
586 if (length
- (12+offset
) < 4)
588 nmb
->question
.question_type
= RSVAL(inbuf
,12+offset
);
589 nmb
->question
.question_class
= RSVAL(inbuf
,12+offset
+2);
596 /* and any resource records */
597 if (nmb
->header
.ancount
&&
598 !parse_alloc_res_rec(inbuf
,&offset
,length
,&nmb
->answers
,
599 nmb
->header
.ancount
))
602 if (nmb
->header
.nscount
&&
603 !parse_alloc_res_rec(inbuf
,&offset
,length
,&nmb
->nsrecs
,
604 nmb
->header
.nscount
))
607 if (nmb
->header
.arcount
&&
608 !parse_alloc_res_rec(inbuf
,&offset
,length
,
609 &nmb
->additional
, nmb
->header
.arcount
))
615 /*******************************************************************
616 'Copy constructor' for an nmb packet.
617 ******************************************************************/
619 static struct packet_struct
*copy_nmb_packet(struct packet_struct
*packet
)
621 struct nmb_packet
*nmb
;
622 struct nmb_packet
*copy_nmb
;
623 struct packet_struct
*pkt_copy
;
625 if(( pkt_copy
= SMB_MALLOC_P(struct packet_struct
)) == NULL
) {
626 DEBUG(0,("copy_nmb_packet: malloc fail.\n"));
630 /* Structure copy of entire thing. */
634 /* Ensure this copy is not locked. */
635 pkt_copy
->locked
= False
;
636 pkt_copy
->recv_fd
= -1;
637 pkt_copy
->send_fd
= -1;
639 /* Ensure this copy has no resource records. */
640 nmb
= &packet
->packet
.nmb
;
641 copy_nmb
= &pkt_copy
->packet
.nmb
;
643 copy_nmb
->answers
= NULL
;
644 copy_nmb
->nsrecs
= NULL
;
645 copy_nmb
->additional
= NULL
;
647 /* Now copy any resource records. */
650 if((copy_nmb
->answers
= SMB_MALLOC_ARRAY(
651 struct res_rec
,nmb
->header
.ancount
)) == NULL
)
653 memcpy((char *)copy_nmb
->answers
, (char *)nmb
->answers
,
654 nmb
->header
.ancount
* sizeof(struct res_rec
));
657 if((copy_nmb
->nsrecs
= SMB_MALLOC_ARRAY(
658 struct res_rec
, nmb
->header
.nscount
)) == NULL
)
660 memcpy((char *)copy_nmb
->nsrecs
, (char *)nmb
->nsrecs
,
661 nmb
->header
.nscount
* sizeof(struct res_rec
));
663 if (nmb
->additional
) {
664 if((copy_nmb
->additional
= SMB_MALLOC_ARRAY(
665 struct res_rec
, nmb
->header
.arcount
)) == NULL
)
667 memcpy((char *)copy_nmb
->additional
, (char *)nmb
->additional
,
668 nmb
->header
.arcount
* sizeof(struct res_rec
));
675 SAFE_FREE(copy_nmb
->answers
);
676 SAFE_FREE(copy_nmb
->nsrecs
);
677 SAFE_FREE(copy_nmb
->additional
);
680 DEBUG(0,("copy_nmb_packet: malloc fail in resource records.\n"));
684 /*******************************************************************
685 'Copy constructor' for a dgram packet.
686 ******************************************************************/
688 static struct packet_struct
*copy_dgram_packet(struct packet_struct
*packet
)
690 struct packet_struct
*pkt_copy
;
692 if(( pkt_copy
= SMB_MALLOC_P(struct packet_struct
)) == NULL
) {
693 DEBUG(0,("copy_dgram_packet: malloc fail.\n"));
697 /* Structure copy of entire thing. */
701 /* Ensure this copy is not locked. */
702 pkt_copy
->locked
= False
;
703 pkt_copy
->recv_fd
= -1;
704 pkt_copy
->send_fd
= -1;
706 /* There are no additional pointers in a dgram packet,
711 /*******************************************************************
712 'Copy constructor' for a generic packet.
713 ******************************************************************/
715 struct packet_struct
*copy_packet(struct packet_struct
*packet
)
717 if(packet
->packet_type
== NMB_PACKET
)
718 return copy_nmb_packet(packet
);
719 else if (packet
->packet_type
== DGRAM_PACKET
)
720 return copy_dgram_packet(packet
);
724 /*******************************************************************
725 Free up any resources associated with an nmb packet.
726 ******************************************************************/
728 static void free_nmb_packet(struct nmb_packet
*nmb
)
730 SAFE_FREE(nmb
->answers
);
731 SAFE_FREE(nmb
->nsrecs
);
732 SAFE_FREE(nmb
->additional
);
735 /*******************************************************************
736 Free up any resources associated with a dgram packet.
737 ******************************************************************/
739 static void free_dgram_packet(struct dgram_packet
*nmb
)
741 /* We have nothing to do for a dgram packet. */
744 /*******************************************************************
745 Free up any resources associated with a packet.
746 ******************************************************************/
748 void free_packet(struct packet_struct
*packet
)
752 if (packet
->packet_type
== NMB_PACKET
)
753 free_nmb_packet(&packet
->packet
.nmb
);
754 else if (packet
->packet_type
== DGRAM_PACKET
)
755 free_dgram_packet(&packet
->packet
.dgram
);
756 ZERO_STRUCTPN(packet
);
760 int packet_trn_id(struct packet_struct
*p
)
763 switch (p
->packet_type
) {
765 result
= p
->packet
.nmb
.header
.name_trn_id
;
768 result
= p
->packet
.dgram
.header
.dgm_id
;
776 /*******************************************************************
777 Parse a packet buffer into a packet structure.
778 ******************************************************************/
780 struct packet_struct
*parse_packet(char *buf
,int length
,
781 enum packet_type packet_type
,
785 struct packet_struct
*p
;
788 p
= SMB_MALLOC_P(struct packet_struct
);
792 ZERO_STRUCTP(p
); /* initialize for possible padding */
799 p
->timestamp
= time(NULL
);
800 p
->packet_type
= packet_type
;
802 switch (packet_type
) {
804 ok
= parse_nmb(buf
,length
,&p
->packet
.nmb
);
808 ok
= parse_dgram(buf
,length
,&p
->packet
.dgram
);
820 static struct packet_struct
*copy_packet_talloc(
821 TALLOC_CTX
*mem_ctx
, const struct packet_struct
*src
)
823 struct packet_struct
*pkt
;
825 pkt
= talloc_memdup(mem_ctx
, src
, sizeof(struct packet_struct
));
833 if (src
->packet_type
== NMB_PACKET
) {
834 const struct nmb_packet
*nsrc
= &src
->packet
.nmb
;
835 struct nmb_packet
*ndst
= &pkt
->packet
.nmb
;
837 if (nsrc
->answers
!= NULL
) {
838 ndst
->answers
= talloc_memdup(
840 sizeof(struct res_rec
) * nsrc
->header
.ancount
);
841 if (ndst
->answers
== NULL
) {
845 if (nsrc
->nsrecs
!= NULL
) {
846 ndst
->nsrecs
= talloc_memdup(
848 sizeof(struct res_rec
) * nsrc
->header
.nscount
);
849 if (ndst
->nsrecs
== NULL
) {
853 if (nsrc
->additional
!= NULL
) {
854 ndst
->additional
= talloc_memdup(
855 pkt
, nsrc
->additional
,
856 sizeof(struct res_rec
) * nsrc
->header
.arcount
);
857 if (ndst
->additional
== NULL
) {
866 * DGRAM packets have no substructures
874 struct packet_struct
*parse_packet_talloc(TALLOC_CTX
*mem_ctx
,
875 char *buf
,int length
,
876 enum packet_type packet_type
,
880 struct packet_struct
*pkt
, *result
;
882 pkt
= parse_packet(buf
, length
, packet_type
, ip
, port
);
886 result
= copy_packet_talloc(mem_ctx
, pkt
);
891 /*******************************************************************
892 Send a udp packet on a already open socket.
893 ******************************************************************/
895 static bool send_udp(int fd
,char *buf
,int len
,struct in_addr ip
,int port
)
899 struct sockaddr_in sock_out
;
901 /* set the address and port */
902 memset((char *)&sock_out
,'\0',sizeof(sock_out
));
903 putip((char *)&sock_out
.sin_addr
,(char *)&ip
);
904 sock_out
.sin_port
= htons( port
);
905 sock_out
.sin_family
= AF_INET
;
907 DEBUG( 5, ( "Sending a packet of len %d to (%s) on port %d\n",
908 len
, inet_ntoa(ip
), port
) );
911 * Patch to fix asynch error notifications from Linux kernel.
914 for (i
= 0; i
< 5; i
++) {
915 ret
= (sendto(fd
,buf
,len
,0,(struct sockaddr
*)&sock_out
,
916 sizeof(sock_out
)) >= 0);
917 if (ret
|| errno
!= ECONNREFUSED
)
922 DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n",
923 inet_ntoa(ip
),port
,strerror(errno
)));
928 /*******************************************************************
929 Build a dgram packet ready for sending.
930 If buf == NULL this is a length calculation.
931 ******************************************************************/
933 static int build_dgram(char *buf
, size_t len
, struct dgram_packet
*dgram
)
935 unsigned char *ubuf
= (unsigned char *)buf
;
938 /* put in the header */
940 ubuf
[0] = dgram
->header
.msg_type
;
941 ubuf
[1] = (((int)dgram
->header
.flags
.node_type
)<<2);
942 if (dgram
->header
.flags
.more
)
944 if (dgram
->header
.flags
.first
)
946 RSSVAL(ubuf
,2,dgram
->header
.dgm_id
);
947 putip(ubuf
+4,(char *)&dgram
->header
.source_ip
);
948 RSSVAL(ubuf
,8,dgram
->header
.source_port
);
949 RSSVAL(ubuf
,12,dgram
->header
.packet_offset
);
954 if (dgram
->header
.msg_type
== 0x10 ||
955 dgram
->header
.msg_type
== 0x11 ||
956 dgram
->header
.msg_type
== 0x12) {
957 offset
+= put_nmb_name((char *)ubuf
,len
,offset
,&dgram
->source_name
);
958 offset
+= put_nmb_name((char *)ubuf
,len
,offset
,&dgram
->dest_name
);
962 memcpy(ubuf
+offset
,dgram
->data
,dgram
->datasize
);
964 offset
+= dgram
->datasize
;
966 /* automatically set the dgm_length
967 * NOTE: RFC1002 says the dgm_length does *not*
968 * include the fourteen-byte header. crh
970 dgram
->header
.dgm_length
= (offset
- 14);
972 RSSVAL(ubuf
,10,dgram
->header
.dgm_length
);
978 /*******************************************************************
980 *******************************************************************/
982 void make_nmb_name( struct nmb_name
*n
, const char *name
, int type
)
985 memset( (char *)n
, '\0', sizeof(struct nmb_name
) );
986 fstrcpy(unix_name
, name
);
987 (void)strupper_m(unix_name
);
988 push_ascii(n
->name
, unix_name
, sizeof(n
->name
), STR_TERMINATE
);
989 n
->name_type
= (unsigned int)type
& 0xFF;
990 push_ascii(n
->scope
, lp_netbios_scope(), 64, STR_TERMINATE
);
993 /*******************************************************************
994 Compare two nmb names
995 ******************************************************************/
997 bool nmb_name_equal(struct nmb_name
*n1
, struct nmb_name
*n2
)
999 return ((n1
->name_type
== n2
->name_type
) &&
1000 strequal(n1
->name
,n2
->name
) &&
1001 strequal(n1
->scope
,n2
->scope
));
1004 /*******************************************************************
1005 Build a nmb packet ready for sending.
1006 If buf == NULL this is a length calculation.
1007 ******************************************************************/
1009 static int build_nmb(char *buf
, size_t len
, struct nmb_packet
*nmb
)
1011 unsigned char *ubuf
= (unsigned char *)buf
;
1014 if (len
&& len
< 12) {
1018 /* put in the header */
1020 RSSVAL(ubuf
,offset
,nmb
->header
.name_trn_id
);
1021 ubuf
[offset
+2] = (nmb
->header
.opcode
& 0xF) << 3;
1022 if (nmb
->header
.response
)
1023 ubuf
[offset
+2] |= (1<<7);
1024 if (nmb
->header
.nm_flags
.authoritative
&&
1025 nmb
->header
.response
)
1026 ubuf
[offset
+2] |= 0x4;
1027 if (nmb
->header
.nm_flags
.trunc
)
1028 ubuf
[offset
+2] |= 0x2;
1029 if (nmb
->header
.nm_flags
.recursion_desired
)
1030 ubuf
[offset
+2] |= 0x1;
1031 if (nmb
->header
.nm_flags
.recursion_available
&&
1032 nmb
->header
.response
)
1033 ubuf
[offset
+3] |= 0x80;
1034 if (nmb
->header
.nm_flags
.bcast
)
1035 ubuf
[offset
+3] |= 0x10;
1036 ubuf
[offset
+3] |= (nmb
->header
.rcode
& 0xF);
1038 RSSVAL(ubuf
,offset
+4,nmb
->header
.qdcount
);
1039 RSSVAL(ubuf
,offset
+6,nmb
->header
.ancount
);
1040 RSSVAL(ubuf
,offset
+8,nmb
->header
.nscount
);
1041 RSSVAL(ubuf
,offset
+10,nmb
->header
.arcount
);
1045 if (nmb
->header
.qdcount
) {
1046 /* XXXX this doesn't handle a qdcount of > 1 */
1049 int extra
= put_nmb_name(NULL
,0,offset
,
1050 &nmb
->question
.question_name
);
1051 if (offset
+ extra
> len
) {
1055 offset
+= put_nmb_name((char *)ubuf
,len
,offset
,
1056 &nmb
->question
.question_name
);
1058 RSSVAL(ubuf
,offset
,nmb
->question
.question_type
);
1059 RSSVAL(ubuf
,offset
+2,nmb
->question
.question_class
);
1064 if (nmb
->header
.ancount
) {
1067 int extra
= put_res_rec(NULL
,0,offset
,nmb
->answers
,
1068 nmb
->header
.ancount
);
1069 if (offset
+ extra
> len
) {
1073 offset
+= put_res_rec((char *)ubuf
,len
,offset
,nmb
->answers
,
1074 nmb
->header
.ancount
);
1077 if (nmb
->header
.nscount
) {
1080 int extra
= put_res_rec(NULL
,0,offset
,nmb
->nsrecs
,
1081 nmb
->header
.nscount
);
1082 if (offset
+ extra
> len
) {
1086 offset
+= put_res_rec((char *)ubuf
,len
,offset
,nmb
->nsrecs
,
1087 nmb
->header
.nscount
);
1091 * The spec says we must put compressed name pointers
1092 * in the following outgoing packets :
1093 * NAME_REGISTRATION_REQUEST, NAME_REFRESH_REQUEST,
1094 * NAME_RELEASE_REQUEST.
1097 if((nmb
->header
.response
== False
) &&
1098 ((nmb
->header
.opcode
== NMB_NAME_REG_OPCODE
) ||
1099 (nmb
->header
.opcode
== NMB_NAME_RELEASE_OPCODE
) ||
1100 (nmb
->header
.opcode
== NMB_NAME_REFRESH_OPCODE_8
) ||
1101 (nmb
->header
.opcode
== NMB_NAME_REFRESH_OPCODE_9
) ||
1102 (nmb
->header
.opcode
== NMB_NAME_MULTIHOMED_REG_OPCODE
)) &&
1103 (nmb
->header
.arcount
== 1)) {
1107 int extra
= put_compressed_name_ptr(NULL
,offset
,
1108 nmb
->additional
,12);
1109 if (offset
+ extra
> len
) {
1113 offset
+= put_compressed_name_ptr(ubuf
,offset
,
1114 nmb
->additional
,12);
1115 } else if (nmb
->header
.arcount
) {
1118 int extra
= put_res_rec(NULL
,0,offset
,nmb
->additional
,
1119 nmb
->header
.arcount
);
1120 if (offset
+ extra
> len
) {
1124 offset
+= put_res_rec((char *)ubuf
,len
,offset
,nmb
->additional
,
1125 nmb
->header
.arcount
);
1130 /*******************************************************************
1132 ******************************************************************/
1134 int build_packet(char *buf
, size_t buflen
, struct packet_struct
*p
)
1138 switch (p
->packet_type
) {
1140 len
= build_nmb(buf
,buflen
,&p
->packet
.nmb
);
1144 len
= build_dgram(buf
,buflen
,&p
->packet
.dgram
);
1151 /*******************************************************************
1152 Send a packet_struct.
1153 ******************************************************************/
1155 bool send_packet(struct packet_struct
*p
)
1160 memset(buf
,'\0',sizeof(buf
));
1162 len
= build_packet(buf
, sizeof(buf
), p
);
1167 return(send_udp(p
->send_fd
,buf
,len
,p
->ip
,p
->port
));
1170 /****************************************************************************
1171 Receive a UDP/138 packet either via UDP or from the unexpected packet
1172 queue. The packet must be a reply packet and have the specified mailslot name
1173 The timeout is in milliseconds.
1174 ***************************************************************************/
1176 /****************************************************************************
1177 See if a datagram has the right mailslot name.
1178 ***************************************************************************/
1180 bool match_mailslot_name(struct packet_struct
*p
, const char *mailslot_name
)
1182 struct dgram_packet
*dgram
= &p
->packet
.dgram
;
1185 buf
= &dgram
->data
[0];
1190 if (memcmp(buf
, mailslot_name
, strlen(mailslot_name
)+1) == 0) {
1197 /****************************************************************************
1198 Return the number of bits that match between two len character buffers
1199 ***************************************************************************/
1201 int matching_len_bits(const unsigned char *p1
, const unsigned char *p2
, size_t len
)
1205 for (i
=0; i
<len
; i
++) {
1214 for (j
=0; j
<8; j
++) {
1215 if ((p1
[i
] & (1<<(7-j
))) != (p2
[i
] & (1<<(7-j
))))
1223 static unsigned char sort_ip
[4];
1225 /****************************************************************************
1226 Compare two query reply records.
1227 ***************************************************************************/
1229 static int name_query_comp(unsigned char *p1
, unsigned char *p2
)
1231 return matching_len_bits(p2
+2, sort_ip
, 4) -
1232 matching_len_bits(p1
+2, sort_ip
, 4);
1235 /****************************************************************************
1236 Sort a set of 6 byte name query response records so that the IPs that
1237 have the most leading bits in common with the specified address come first.
1238 ***************************************************************************/
1240 void sort_query_replies(char *data
, int n
, struct in_addr ip
)
1245 putip(sort_ip
, (char *)&ip
);
1248 this can't use TYPESAFE_QSORT() as the types are wrong.
1249 It should be fixed to use a real type instead of char*
1251 qsort(data
, n
, 6, QSORT_CAST name_query_comp
);
1254 /****************************************************************************
1255 Interpret the weird netbios "name" into a unix fstring. Return the name type.
1256 Returns -1 on error.
1257 ****************************************************************************/
1259 static int name_interpret(unsigned char *buf
, size_t buf_len
,
1260 unsigned char *in
, fstring name
)
1262 unsigned char *end_ptr
= buf
+ buf_len
;
1266 unsigned char *out
= (unsigned char *)out_string
;
1270 if (in
>= end_ptr
) {
1280 if (&in
[1] >= end_ptr
) {
1283 if (in
[0] < 'A' || in
[0] > 'P' || in
[1] < 'A' || in
[1] > 'P') {
1287 *out
= ((in
[0]-'A')<<4) + (in
[1]-'A');
1290 if (PTR_DIFF(out
,out_string
) >= sizeof(fstring
)) {
1297 pull_ascii_fstring(name
, out_string
);
1302 /****************************************************************************
1303 Mangle a name into netbios format.
1304 Note: <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
1305 ****************************************************************************/
1307 char *name_mangle(TALLOC_CTX
*mem_ctx
, const char *In
, char name_type
)
1315 result
= talloc_array(mem_ctx
, char, 33 + strlen(lp_netbios_scope()) + 2);
1316 if (result
== NULL
) {
1321 /* Safely copy the input string, In, into buf[]. */
1322 if (strcmp(In
,"*") == 0)
1323 put_name(buf
, "*", '\0', 0x00);
1325 /* We use an fstring here as mb dos names can expend x3 when
1330 pull_ascii_fstring(buf_unix
, In
);
1331 if (!strupper_m(buf_unix
)) {
1335 push_ascii_nstring(buf_dos
, buf_unix
);
1336 put_name(buf
, buf_dos
, ' ', name_type
);
1339 /* Place the length of the first field into the output buffer. */
1343 /* Now convert the name to the rfc1001/1002 format. */
1344 for( i
= 0; i
< MAX_NETBIOSNAME_LEN
; i
++ ) {
1345 p
[i
*2] = ( (buf
[i
] >> 4) & 0x000F ) + 'A';
1346 p
[(i
*2)+1] = (buf
[i
] & 0x000F) + 'A';
1351 /* Add the scope string. */
1352 for( i
= 0, len
= 0; *(lp_netbios_scope()) != '\0'; i
++, len
++ ) {
1353 switch( (lp_netbios_scope())[i
] ) {
1365 p
[len
+1] = (lp_netbios_scope())[i
];
1373 /****************************************************************************
1374 Find a pointer to a netbios name.
1375 ****************************************************************************/
1377 static unsigned char *name_ptr(unsigned char *buf
, size_t buf_len
, unsigned int ofs
)
1379 unsigned char c
= 0;
1381 if (ofs
> buf_len
|| buf_len
< 1) {
1385 c
= *(unsigned char *)(buf
+ofs
);
1386 if ((c
& 0xC0) == 0xC0) {
1389 if (ofs
> buf_len
- 1) {
1392 l
= RSVAL(buf
, ofs
) & 0x3FFF;
1396 DEBUG(5,("name ptr to pos %d from %d is %s\n",l
,ofs
,buf
+l
));
1403 /****************************************************************************
1404 Extract a netbios name from a buf (into a unix string) return name type.
1405 Returns -1 on error.
1406 ****************************************************************************/
1408 int name_extract(unsigned char *buf
, size_t buf_len
, unsigned int ofs
, fstring name
)
1410 unsigned char *p
= name_ptr(buf
,buf_len
,ofs
);
1416 return(name_interpret(buf
,buf_len
,p
,name
));
1419 /****************************************************************************
1420 Return the total storage length of a mangled name.
1421 Returns -1 on error.
1422 ****************************************************************************/
1424 int name_len(unsigned char *s1
, size_t buf_len
)
1426 /* NOTE: this argument _must_ be unsigned */
1427 unsigned char *s
= (unsigned char *)s1
;
1433 /* If the two high bits of the byte are set, return 2. */
1434 if (0xC0 == (*s
& 0xC0)) {
1441 /* Add up the length bytes. */
1442 for (len
= 1; (*s
); s
+= (*s
) + 1) {
1444 if (len
> buf_len
) {
1452 /*******************************************************************
1453 Setup the word count and byte count for a client smb message.
1454 ********************************************************************/
1456 int cli_set_message(char *buf
,int num_words
,int num_bytes
,bool zero
)
1458 if (zero
&& (num_words
|| num_bytes
)) {
1459 memset(buf
+ smb_size
,'\0',num_words
*2 + num_bytes
);
1461 SCVAL(buf
,smb_wct
,num_words
);
1462 SSVAL(buf
,smb_vwv
+ num_words
*SIZEOFWORD
,num_bytes
);
1463 smb_setlen(buf
,smb_size
+ num_words
*2 + num_bytes
- 4);
1464 return (smb_size
+ num_words
*2 + num_bytes
);