CVE-2020-10730: selftest: Add test to confirm VLV interaction with ASQ
[Samba.git] / source3 / libsmb / nmblib.c
bloba5e691a1c86081363752e025459e46cad2983f03
1 /*
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/>.
22 #include "includes.h"
23 #include "libsmb/nmblib.h"
25 static const struct opcode_names {
26 const char *nmb_opcode_name;
27 int opcode;
28 } nmb_header_opcode_names[] = {
29 {"Query", 0 },
30 {"Registration", 5 },
31 {"Release", 6 },
32 {"WACK", 7 },
33 {"Refresh", 8 },
34 {"Refresh(altcode)", 9 },
35 {"Multi-homed Registration", 15 },
36 {0, -1 }
39 /****************************************************************************
40 Lookup a nmb opcode name.
41 ****************************************************************************/
43 static const char *lookup_opcode_name( int opcode )
45 const struct opcode_names *op_namep;
46 int i;
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)
62 int i, j;
64 DEBUGADD( 4, ( " %s: nmb_name=%s rr_type=%d rr_class=%d ttl=%d\n",
65 hdr,
66 nmb_namestr(&res->rr_name),
67 res->rr_type,
68 res->rr_class,
69 res->ttl ) );
71 if (res->rdlength == 0) {
72 return;
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)
81 x = '.';
83 if (i+j >= res->rdlength)
84 break;
85 DEBUGADD(4, ("%c", x));
88 DEBUGADD(4, (" hex "));
90 for (j = 0; j < MAX_NETBIOSNAME_LEN; j++) {
91 if (i+j >= res->rdlength)
92 break;
93 DEBUGADD(4, ("%02X", (unsigned char)res->rdata[i+j]));
96 DEBUGADD(4, ("\n"));
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),
114 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",
125 nmb->header.rcode,
126 nmb->header.qdcount,
127 nmb->header.ancount,
128 nmb->header.nscount,
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)
157 int loop_count=0;
159 while ((ubuf[*offset] & 0xC0) == 0xC0) {
160 if (!*got_pointer)
161 (*ret) += 2;
162 (*got_pointer)=True;
163 if (*offset > length - 2) {
164 return False;
166 (*offset) = ((ubuf[*offset] & ~0xC0)<<8) | ubuf[(*offset)+1];
167 if (loop_count++ == 10 ||
168 (*offset) < 0 || (*offset)>(length-2)) {
169 return False;
172 return True;
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)
182 size_t m,n=0;
183 unsigned char *ubuf = (unsigned char *)inbuf;
184 int ret = 0;
185 bool got_pointer=False;
186 size_t loop_count=0;
187 int offset = ofs;
189 if (length - offset < 2)
190 return(0);
192 /* handle initial name pointers */
193 if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret))
194 return(0);
196 m = ubuf[offset];
198 /* m must be 32 to exactly fill in the 16 bytes of the netbios name */
199 if (m != 32) {
200 return 0;
202 /* Cannot go past length. */
203 if (offset+m+2 > length) {
204 return 0;
207 memset((char *)name,'\0',sizeof(*name));
209 /* the "compressed" part */
210 if (!got_pointer)
211 ret += m + 2;
212 offset++;
213 while (m > 0) {
214 unsigned char c1,c2;
215 c1 = ubuf[offset++]-'A';
216 c2 = ubuf[offset++]-'A';
217 if ((c1 & 0xF0) || (c2 & 0xF0)) {
218 return(0);
220 if (n >= sizeof(name->name)) {
221 return 0;
223 name->name[n++] = (c1<<4) | c2;
224 m -= 2;
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) {
231 return 0;
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 */
239 name->name[15] = 0;
240 n = 14;
241 while (n && name->name[n]==' ')
242 name->name[n--] = 0;
244 /* now the domain parts (if any) */
245 n = 0;
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))
249 return(0);
251 m = ubuf[offset];
253 * Don't allow null domain parts.
255 if (!m)
256 return(0);
257 if (!got_pointer)
258 ret += m+1;
259 if (n)
260 name->scope[n++] = '.';
261 if (m+2+offset>length || n+m+1>sizeof(name->scope))
262 return(0);
263 offset++;
264 while (m--)
265 name->scope[n++] = (char)ubuf[offset++];
268 * Watch for malicious loops.
270 if (loop_count++ == 10)
271 return 0;
273 name->scope[n++] = 0;
275 return(ret);
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
298 compressed name.
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)
309 int ret,m;
310 nstring buf1;
311 char *p;
313 if (strcmp(name->name,"*") == 0) {
314 /* special case for wildcard name */
315 put_name(buf1, "*", '\0', name->name_type);
316 } else {
317 put_name(buf1, name->name, ' ', name->name_type);
320 if (buf) {
321 if (offset >= buflen) {
322 return 0;
324 buf[offset] = 0x20;
327 ret = 34;
329 for (m=0;m<MAX_NETBIOSNAME_LEN;m++) {
330 if (buf) {
331 if (offset+2+2*m >= buflen) {
332 return 0;
334 buf[offset+1+2*m] = 'A' + ((buf1[m]>>4)&0xF);
335 buf[offset+2+2*m] = 'A' + (buf1[m]&0xF);
338 offset += 33;
340 if (buf) {
341 if (offset >= buflen) {
342 return 0;
344 buf[offset] = 0;
347 if (name->scope[0]) {
348 /* XXXX this scope handling needs testing */
349 size_t scopenamelen = strlen(name->scope) + 1;
350 ret += scopenamelen;
351 if (buf) {
352 if (offset+1+scopenamelen >= buflen) {
353 return 0;
355 strlcpy(&buf[offset+1],name->scope,
356 buflen - (offset+1));
358 p = &buf[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) {
363 return 0;
365 p = &buf[offset+1];
367 buf[offset] = strlen(&buf[offset+1]);
371 return ret;
374 /*******************************************************************
375 Useful for debugging messages.
376 ******************************************************************/
378 char *nmb_namestr(const struct nmb_name *n)
380 fstring name;
381 char *result;
383 pull_ascii_fstring(name, n->name);
384 if (!n->scope[0])
385 result = talloc_asprintf(talloc_tos(), "%s<%02x>", name,
386 n->name_type);
387 else
388 result = talloc_asprintf(talloc_tos(), "%s<%02x>.%s", name,
389 n->name_type, n->scope);
391 SMB_ASSERT(result != NULL);
392 return result;
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)
402 int i;
404 *recs = SMB_MALLOC_ARRAY(struct res_rec, count);
405 if (!*recs)
406 return(False);
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);
413 (*offset) += l;
414 if (!l || (*offset)+10 > length) {
415 SAFE_FREE(*recs);
416 return(False);
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);
422 (*offset) += 10;
423 if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) ||
424 (*offset)+(*recs)[i].rdlength > length) {
425 SAFE_FREE(*recs);
426 return(False);
428 memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength);
429 (*offset) += (*recs)[i].rdlength;
431 return(True);
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)
441 int ret=0;
442 int i;
444 for (i=0;i<count;i++) {
445 int l = put_nmb_name(buf,buflen,offset,&recs[i].rr_name);
446 offset += l;
447 ret += l;
448 if (buf) {
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;
459 return ret;
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,
468 int offset,
469 struct res_rec *rec,
470 int ptr_offset)
472 int ret=offset;
473 if (buf) {
474 buf[offset] = (0xC0 | ((ptr_offset >> 8) & 0xFF));
475 buf[offset+1] = (ptr_offset & 0xFF);
477 offset += 2;
478 if (buf) {
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);
488 return 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)
500 size_t offset;
501 int flags;
503 memset((char *)dgram,'\0',sizeof(*dgram));
505 if (length < 14)
506 return(False);
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);
511 if (flags & 1)
512 dgram->header.flags.more = True;
513 if (flags & 2)
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);
521 offset = 14;
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,
529 &dgram->dest_name);
532 if (offset >= length || (length-offset > sizeof(dgram->data)))
533 return(False);
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);
544 return(True);
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)
554 int nm_flags,offset;
556 memset((char *)nmb,'\0',sizeof(*nmb));
558 if (length < 12)
559 return(False);
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);
583 if (!offset)
584 return(False);
586 if (length - (12+offset) < 4)
587 return(False);
588 nmb->question.question_type = RSVAL(inbuf,12+offset);
589 nmb->question.question_class = RSVAL(inbuf,12+offset+2);
591 offset += 12+4;
592 } else {
593 offset = 12;
596 /* and any resource records */
597 if (nmb->header.ancount &&
598 !parse_alloc_res_rec(inbuf,&offset,length,&nmb->answers,
599 nmb->header.ancount))
600 return(False);
602 if (nmb->header.nscount &&
603 !parse_alloc_res_rec(inbuf,&offset,length,&nmb->nsrecs,
604 nmb->header.nscount))
605 return(False);
607 if (nmb->header.arcount &&
608 !parse_alloc_res_rec(inbuf,&offset,length,
609 &nmb->additional, nmb->header.arcount))
610 return(False);
612 return(True);
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"));
627 return NULL;
630 /* Structure copy of entire thing. */
632 *pkt_copy = *packet;
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. */
649 if (nmb->answers) {
650 if((copy_nmb->answers = SMB_MALLOC_ARRAY(
651 struct res_rec,nmb->header.ancount)) == NULL)
652 goto free_and_exit;
653 memcpy((char *)copy_nmb->answers, (char *)nmb->answers,
654 nmb->header.ancount * sizeof(struct res_rec));
656 if (nmb->nsrecs) {
657 if((copy_nmb->nsrecs = SMB_MALLOC_ARRAY(
658 struct res_rec, nmb->header.nscount)) == NULL)
659 goto free_and_exit;
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)
666 goto free_and_exit;
667 memcpy((char *)copy_nmb->additional, (char *)nmb->additional,
668 nmb->header.arcount * sizeof(struct res_rec));
671 return pkt_copy;
673 free_and_exit:
675 SAFE_FREE(copy_nmb->answers);
676 SAFE_FREE(copy_nmb->nsrecs);
677 SAFE_FREE(copy_nmb->additional);
678 SAFE_FREE(pkt_copy);
680 DEBUG(0,("copy_nmb_packet: malloc fail in resource records.\n"));
681 return NULL;
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"));
694 return NULL;
697 /* Structure copy of entire thing. */
699 *pkt_copy = *packet;
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,
707 we are finished. */
708 return pkt_copy;
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);
721 return NULL;
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)
750 if (packet->locked)
751 return;
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);
757 SAFE_FREE(packet);
760 int packet_trn_id(struct packet_struct *p)
762 int result;
763 switch (p->packet_type) {
764 case NMB_PACKET:
765 result = p->packet.nmb.header.name_trn_id;
766 break;
767 case DGRAM_PACKET:
768 result = p->packet.dgram.header.dgm_id;
769 break;
770 default:
771 result = -1;
773 return result;
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,
782 struct in_addr ip,
783 int port)
785 struct packet_struct *p;
786 bool ok=False;
788 p = SMB_MALLOC_P(struct packet_struct);
789 if (!p)
790 return(NULL);
792 ZERO_STRUCTP(p); /* initialize for possible padding */
794 p->next = NULL;
795 p->prev = NULL;
796 p->ip = ip;
797 p->port = port;
798 p->locked = False;
799 p->timestamp = time(NULL);
800 p->packet_type = packet_type;
802 switch (packet_type) {
803 case NMB_PACKET:
804 ok = parse_nmb(buf,length,&p->packet.nmb);
805 break;
807 case DGRAM_PACKET:
808 ok = parse_dgram(buf,length,&p->packet.dgram);
809 break;
812 if (!ok) {
813 free_packet(p);
814 return NULL;
817 return p;
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));
826 if (pkt == NULL) {
827 return NULL;
829 pkt->locked = false;
830 pkt->recv_fd = -1;
831 pkt->send_fd = -1;
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(
839 pkt, nsrc->answers,
840 sizeof(struct res_rec) * nsrc->header.ancount);
841 if (ndst->answers == NULL) {
842 goto fail;
845 if (nsrc->nsrecs != NULL) {
846 ndst->nsrecs = talloc_memdup(
847 pkt, nsrc->nsrecs,
848 sizeof(struct res_rec) * nsrc->header.nscount);
849 if (ndst->nsrecs == NULL) {
850 goto fail;
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) {
858 goto fail;
863 return pkt;
866 * DGRAM packets have no substructures
869 fail:
870 TALLOC_FREE(pkt);
871 return NULL;
874 struct packet_struct *parse_packet_talloc(TALLOC_CTX *mem_ctx,
875 char *buf,int length,
876 enum packet_type packet_type,
877 struct in_addr ip,
878 int port)
880 struct packet_struct *pkt, *result;
882 pkt = parse_packet(buf, length, packet_type, ip, port);
883 if (pkt == NULL) {
884 return NULL;
886 result = copy_packet_talloc(mem_ctx, pkt);
887 free_packet(pkt);
888 return result;
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)
897 bool ret = False;
898 int i;
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)
918 break;
921 if (!ret)
922 DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n",
923 inet_ntoa(ip),port,strerror(errno)));
925 return(ret);
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;
936 int offset=0;
938 /* put in the header */
939 if (buf) {
940 ubuf[0] = dgram->header.msg_type;
941 ubuf[1] = (((int)dgram->header.flags.node_type)<<2);
942 if (dgram->header.flags.more)
943 ubuf[1] |= 1;
944 if (dgram->header.flags.first)
945 ubuf[1] |= 2;
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);
952 offset = 14;
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);
961 if (buf) {
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);
971 if (buf) {
972 RSSVAL(ubuf,10,dgram->header.dgm_length);
975 return offset;
978 /*******************************************************************
979 Build a nmb name
980 *******************************************************************/
982 void make_nmb_name( struct nmb_name *n, const char *name, int type)
984 fstring unix_name;
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;
1012 int offset=0;
1014 if (len && len < 12) {
1015 return 0;
1018 /* put in the header */
1019 if (buf) {
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);
1044 offset += 12;
1045 if (nmb->header.qdcount) {
1046 /* XXXX this doesn't handle a qdcount of > 1 */
1047 if (len) {
1048 /* Length check. */
1049 int extra = put_nmb_name(NULL,0,offset,
1050 &nmb->question.question_name);
1051 if (offset + extra > len) {
1052 return 0;
1055 offset += put_nmb_name((char *)ubuf,len,offset,
1056 &nmb->question.question_name);
1057 if (buf) {
1058 RSSVAL(ubuf,offset,nmb->question.question_type);
1059 RSSVAL(ubuf,offset+2,nmb->question.question_class);
1061 offset += 4;
1064 if (nmb->header.ancount) {
1065 if (len) {
1066 /* Length check. */
1067 int extra = put_res_rec(NULL,0,offset,nmb->answers,
1068 nmb->header.ancount);
1069 if (offset + extra > len) {
1070 return 0;
1073 offset += put_res_rec((char *)ubuf,len,offset,nmb->answers,
1074 nmb->header.ancount);
1077 if (nmb->header.nscount) {
1078 if (len) {
1079 /* Length check. */
1080 int extra = put_res_rec(NULL,0,offset,nmb->nsrecs,
1081 nmb->header.nscount);
1082 if (offset + extra > len) {
1083 return 0;
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)) {
1105 if (len) {
1106 /* Length check. */
1107 int extra = put_compressed_name_ptr(NULL,offset,
1108 nmb->additional,12);
1109 if (offset + extra > len) {
1110 return 0;
1113 offset += put_compressed_name_ptr(ubuf,offset,
1114 nmb->additional,12);
1115 } else if (nmb->header.arcount) {
1116 if (len) {
1117 /* Length check. */
1118 int extra = put_res_rec(NULL,0,offset,nmb->additional,
1119 nmb->header.arcount);
1120 if (offset + extra > len) {
1121 return 0;
1124 offset += put_res_rec((char *)ubuf,len,offset,nmb->additional,
1125 nmb->header.arcount);
1127 return offset;
1130 /*******************************************************************
1131 Linearise a packet.
1132 ******************************************************************/
1134 int build_packet(char *buf, size_t buflen, struct packet_struct *p)
1136 int len = 0;
1138 switch (p->packet_type) {
1139 case NMB_PACKET:
1140 len = build_nmb(buf,buflen,&p->packet.nmb);
1141 break;
1143 case DGRAM_PACKET:
1144 len = build_dgram(buf,buflen,&p->packet.dgram);
1145 break;
1148 return len;
1151 /*******************************************************************
1152 Send a packet_struct.
1153 ******************************************************************/
1155 bool send_packet(struct packet_struct *p)
1157 char buf[1024];
1158 int len=0;
1160 memset(buf,'\0',sizeof(buf));
1162 len = build_packet(buf, sizeof(buf), p);
1164 if (!len)
1165 return(False);
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;
1183 char *buf;
1185 buf = &dgram->data[0];
1186 buf -= 4;
1188 buf = smb_buf(buf);
1190 if (memcmp(buf, mailslot_name, strlen(mailslot_name)+1) == 0) {
1191 return True;
1194 return False;
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)
1203 size_t i, j;
1204 int ret = 0;
1205 for (i=0; i<len; i++) {
1206 if (p1[i] != p2[i])
1207 break;
1208 ret += 8;
1211 if (i==len)
1212 return ret;
1214 for (j=0; j<8; j++) {
1215 if ((p1[i] & (1<<(7-j))) != (p2[i] & (1<<(7-j))))
1216 break;
1217 ret++;
1220 return ret;
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)
1242 if (n <= 1)
1243 return;
1245 putip(sort_ip, (char *)&ip);
1247 /* TODO:
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;
1263 int ret;
1264 unsigned int len;
1265 fstring out_string;
1266 unsigned char *out = (unsigned char *)out_string;
1268 *out=0;
1270 if (in >= end_ptr) {
1271 return -1;
1273 len = (*in++) / 2;
1275 if (len<1) {
1276 return -1;
1279 while (len--) {
1280 if (&in[1] >= end_ptr) {
1281 return -1;
1283 if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
1284 *out = 0;
1285 return(0);
1287 *out = ((in[0]-'A')<<4) + (in[1]-'A');
1288 in += 2;
1289 out++;
1290 if (PTR_DIFF(out,out_string) >= sizeof(fstring)) {
1291 return -1;
1294 ret = out[-1];
1295 out[-1] = 0;
1297 pull_ascii_fstring(name, out_string);
1299 return(ret);
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)
1309 int i;
1310 int len;
1311 nstring buf;
1312 char *result;
1313 char *p;
1315 result = talloc_array(mem_ctx, char, 33 + strlen(lp_netbios_scope()) + 2);
1316 if (result == NULL) {
1317 return NULL;
1319 p = result;
1321 /* Safely copy the input string, In, into buf[]. */
1322 if (strcmp(In,"*") == 0)
1323 put_name(buf, "*", '\0', 0x00);
1324 else {
1325 /* We use an fstring here as mb dos names can expend x3 when
1326 going to utf8. */
1327 fstring buf_unix;
1328 nstring buf_dos;
1330 pull_ascii_fstring(buf_unix, In);
1331 if (!strupper_m(buf_unix)) {
1332 return NULL;
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. */
1340 p[0] = 32;
1341 p++;
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';
1348 p += 32;
1349 p[0] = '\0';
1351 /* Add the scope string. */
1352 for( i = 0, len = 0; *(lp_netbios_scope()) != '\0'; i++, len++ ) {
1353 switch( (lp_netbios_scope())[i] ) {
1354 case '\0':
1355 p[0] = len;
1356 if( len > 0 )
1357 p[len+1] = 0;
1358 return result;
1359 case '.':
1360 p[0] = len;
1361 p += (len + 1);
1362 len = -1;
1363 break;
1364 default:
1365 p[len+1] = (lp_netbios_scope())[i];
1366 break;
1370 return result;
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) {
1382 return NULL;
1385 c = *(unsigned char *)(buf+ofs);
1386 if ((c & 0xC0) == 0xC0) {
1387 uint16_t l = 0;
1389 if (ofs > buf_len - 1) {
1390 return NULL;
1392 l = RSVAL(buf, ofs) & 0x3FFF;
1393 if (l > buf_len) {
1394 return NULL;
1396 DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
1397 return(buf + l);
1398 } else {
1399 return(buf+ofs);
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);
1412 name[0] = '\0';
1413 if (p == NULL) {
1414 return -1;
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;
1428 int len = 0;
1430 if (buf_len < 1) {
1431 return -1;
1433 /* If the two high bits of the byte are set, return 2. */
1434 if (0xC0 == (*s & 0xC0)) {
1435 if (buf_len < 2) {
1436 return -1;
1438 return(2);
1441 /* Add up the length bytes. */
1442 for (len = 1; (*s); s += (*s) + 1) {
1443 len += *s + 1;
1444 if (len > buf_len) {
1445 return -1;
1449 return(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);