1 /*
2 Unix SMB/CIFS implementation.
3 NBT netbios library routines
4 Copyright (C) Andrew Tridgell 1994-1998
5 Copyright (C) Jeremy Allison 2007
6
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.
11
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.
16
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/>.
19
20 */
21
22 #include "includes.h"
23 #include "libsmb/nmblib.h"
24
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 }
37 };
38
39 /****************************************************************************
40 Lookup a nmb opcode name.
41 ****************************************************************************/
42
lookup_opcode_name(int opcode)43 static const char *lookup_opcode_name( int opcode )
44 {
45 const struct opcode_names *op_namep;
46 int i;
47
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;
52 }
53 return "<unknown opcode>";
54 }
55
56 /****************************************************************************
57 Print out a res_rec structure.
58 ****************************************************************************/
59
debug_nmb_res_rec(struct res_rec * res,const char * hdr)60 static void debug_nmb_res_rec(struct res_rec *res, const char *hdr)
61 {
62 int i, j;
63
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 ) );
70
71 if (res->rdlength == 0) {
72 return;
73 }
74
75 for (i = 0; i < res->rdlength; i+= MAX_NETBIOSNAME_LEN) {
76 DEBUGADD(4, (" %s %3x char ", hdr, i));
77
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 = '.';
82
83 if (i+j >= res->rdlength)
84 break;
85 DEBUGADD(4, ("%c", x));
86 }
87
88 DEBUGADD(4, (" hex "));
89
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]));
94 }
95
96 DEBUGADD(4, ("\n"));
97 }
98 }
99
100 /****************************************************************************
101 Process a nmb packet.
102 ****************************************************************************/
103
debug_nmb_packet(struct packet_struct * p)104 void debug_nmb_packet(struct packet_struct *p)
105 {
106 struct nmb_packet *nmb = &p->packet.nmb;
107
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 );
130 }
131
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) );
137 }
138
139 if (nmb->answers && nmb->header.ancount) {
140 debug_nmb_res_rec(nmb->answers,"answers");
141 }
142 if (nmb->nsrecs && nmb->header.nscount) {
143 debug_nmb_res_rec(nmb->nsrecs,"nsrecs");
144 }
145 if (nmb->additional && nmb->header.arcount) {
146 debug_nmb_res_rec(nmb->additional,"additional");
147 }
148 }
149
150 /*******************************************************************
151 Handle "compressed" name pointers.
152 ******************************************************************/
153
handle_name_ptrs(unsigned char * ubuf,int * offset,int length,bool * got_pointer,int * ret)154 static bool handle_name_ptrs(unsigned char *ubuf,int *offset,int length,
155 bool *got_pointer,int *ret)
156 {
157 int loop_count=0;
158
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;
165 }
166 (*offset) = ((ubuf[*offset] & ~0xC0)<<8) | ubuf[(*offset)+1];
167 if (loop_count++ == 10 ||
168 (*offset) < 0 || (*offset)>(length-2)) {
169 return False;
170 }
171 }
172 return True;
173 }
174
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 ******************************************************************/
179
parse_nmb_name(char * inbuf,int ofs,int length,struct nmb_name * name)180 static int parse_nmb_name(char *inbuf,int ofs,int length, struct nmb_name *name)
181 {
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;
188
189 if (length - offset < 2)
190 return(0);
191
192 /* handle initial name pointers */
193 if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret))
194 return(0);
195
196 m = ubuf[offset];
197
198 /* m must be 32 to exactly fill in the 16 bytes of the netbios name */
199 if (m != 32) {
200 return 0;
201 }
202 /* Cannot go past length. */
203 if (offset+m+2 > length) {
204 return 0;
205 }
206
207 memset((char *)name,'\0',sizeof(*name));
208
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);
219 }
220 if (n >= sizeof(name->name)) {
221 return 0;
222 }
223 name->name[n++] = (c1<<4) | c2;
224 m -= 2;
225 }
226 /*
227 * RFC1002: For a valid NetBIOS name, exiting from the above,
228 * n *must* be MAX_NETBIOSNAME_LEN (16).
229 */
230 if (n != MAX_NETBIOSNAME_LEN) {
231 return 0;
232 }
233
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;
237
238 /* remove trailing spaces */
239 name->name[15] = 0;
240 n = 14;
241 while (n && name->name[n]==' ')
242 name->name[n--] = 0;
243
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);
250
251 m = ubuf[offset];
252 /*
253 * Don't allow null domain parts.
254 */
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++];
266
267 /*
268 * Watch for malicious loops.
269 */
270 if (loop_count++ == 10)
271 return 0;
272 }
273 name->scope[n++] = 0;
274
275 return(ret);
276 }
277
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 ****************************************************************************/
283
put_name(char * dest,const char * name,int pad,unsigned int name_type)284 void put_name(char *dest, const char *name, int pad, unsigned int name_type)
285 {
286 size_t len = strlen(name);
287
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);
292 }
293 dest[MAX_NETBIOSNAME_LEN - 1] = name_type;
294 }
295
296 /*******************************************************************
297 Put a compressed nmb name into a buffer. Return the length of the
298 compressed name.
299
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.
303
304 If buf == NULL this is a length calculation.
305 ******************************************************************/
306
put_nmb_name(char * buf,size_t buflen,int offset,struct nmb_name * name)307 static int put_nmb_name(char *buf, size_t buflen, int offset,struct nmb_name *name)
308 {
309 int ret,m;
310 nstring buf1;
311 char *p;
312
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);
318 }
319
320 if (buf) {
321 if (offset >= buflen) {
322 return 0;
323 }
324 buf[offset] = 0x20;
325 }
326
327 ret = 34;
328
329 for (m=0;m<MAX_NETBIOSNAME_LEN;m++) {
330 if (buf) {
331 if (offset+2+2*m >= buflen) {
332 return 0;
333 }
334 buf[offset+1+2*m] = 'A' + ((buf1[m]>>4)&0xF);
335 buf[offset+2+2*m] = 'A' + (buf1[m]&0xF);
336 }
337 }
338 offset += 33;
339
340 if (buf) {
341 if (offset >= buflen) {
342 return 0;
343 }
344 buf[offset] = 0;
345 }
346
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;
354 }
355 strlcpy(&buf[offset+1],name->scope,
356 buflen - (offset+1));
357
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;
364 }
365 p = &buf[offset+1];
366 }
367 buf[offset] = strlen(&buf[offset+1]);
368 }
369 }
370
371 return ret;
372 }
373
374 /*******************************************************************
375 Useful for debugging messages.
376 ******************************************************************/
377
nmb_namestr(const struct nmb_name * n)378 char *nmb_namestr(const struct nmb_name *n)
379 {
380 fstring name;
381 char *result;
382
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);
390
391 SMB_ASSERT(result != NULL);
392 return result;
393 }
394
395 /*******************************************************************
396 Allocate and parse some resource records.
397 ******************************************************************/
398
parse_alloc_res_rec(char * inbuf,int * offset,int length,struct res_rec ** recs,int count)399 static bool parse_alloc_res_rec(char *inbuf,int *offset,int length,
400 struct res_rec **recs, int count)
401 {
402 int i;
403
404 *recs = SMB_MALLOC_ARRAY(struct res_rec, count);
405 if (!*recs)
406 return(False);
407
408 memset((char *)*recs,'\0',sizeof(**recs)*count);
409
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);
417 }
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);
427 }
428 memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength);
429 (*offset) += (*recs)[i].rdlength;
430 }
431 return(True);
432 }
433
434 /*******************************************************************
435 Put a resource record into a packet.
436 If buf == NULL this is a length calculation.
437 ******************************************************************/
438
put_res_rec(char * buf,size_t buflen,int offset,struct res_rec * recs,int count)439 static int put_res_rec(char *buf, size_t buflen, int offset,struct res_rec *recs,int count)
440 {
441 int ret=0;
442 int i;
443
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);
454 }
455 offset += 10+recs[i].rdlength;
456 ret += 10+recs[i].rdlength;
457 }
458
459 return ret;
460 }
461
462 /*******************************************************************
463 Put a compressed name pointer record into a packet.
464 If buf == NULL this is a length calculation.
465 ******************************************************************/
466
put_compressed_name_ptr(unsigned char * buf,int offset,struct res_rec * rec,int ptr_offset)467 static int put_compressed_name_ptr(unsigned char *buf,
468 int offset,
469 struct res_rec *rec,
470 int ptr_offset)
471 {
472 int ret=offset;
473 if (buf) {
474 buf[offset] = (0xC0 | ((ptr_offset >> 8) & 0xFF));
475 buf[offset+1] = (ptr_offset & 0xFF);
476 }
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);
484 }
485 offset += 10+rec->rdlength;
486 ret = (offset - ret);
487
488 return ret;
489 }
490
491 /*******************************************************************
492 Parse a dgram packet. Return False if the packet can't be parsed
493 or is invalid for some reason, True otherwise.
494
495 This is documented in section 4.4.1 of RFC1002.
496 ******************************************************************/
497
parse_dgram(char * inbuf,int length,struct dgram_packet * dgram)498 static bool parse_dgram(char *inbuf,int length,struct dgram_packet *dgram)
499 {
500 size_t offset;
501 int flags;
502
503 memset((char *)dgram,'\0',sizeof(*dgram));
504
505 if (length < 14)
506 return(False);
507
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);
520
521 offset = 14;
522
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);
530 }
531
532 if (offset >= length || (length-offset > sizeof(dgram->data)))
533 return(False);
534
535 dgram->datasize = length-offset;
536 memcpy(dgram->data,inbuf+offset,dgram->datasize);
537
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);
543
544 return(True);
545 }
546
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 ******************************************************************/
551
parse_nmb(char * inbuf,int length,struct nmb_packet * nmb)552 static bool parse_nmb(char *inbuf,int length,struct nmb_packet *nmb)
553 {
554 int nm_flags,offset;
555
556 memset((char *)nmb,'\0',sizeof(*nmb));
557
558 if (length < 12)
559 return(False);
560
561 /* parse the header */
562 nmb->header.name_trn_id = RSVAL(inbuf,0);
563
564 DEBUG(10,("parse_nmb: packet id = %d\n", nmb->header.name_trn_id));
565
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);
579
580 if (nmb->header.qdcount) {
581 offset = parse_nmb_name(inbuf,12,length,
582 &nmb->question.question_name);
583 if (!offset)
584 return(False);
585
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);
590
591 offset += 12+4;
592 } else {
593 offset = 12;
594 }
595
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);
601
602 if (nmb->header.nscount &&
603 !parse_alloc_res_rec(inbuf,&offset,length,&nmb->nsrecs,
604 nmb->header.nscount))
605 return(False);
606
607 if (nmb->header.arcount &&
608 !parse_alloc_res_rec(inbuf,&offset,length,
609 &nmb->additional, nmb->header.arcount))
610 return(False);
611
612 return(True);
613 }
614
615 /*******************************************************************
616 'Copy constructor' for an nmb packet.
617 ******************************************************************/
618
copy_nmb_packet(struct packet_struct * packet)619 static struct packet_struct *copy_nmb_packet(struct packet_struct *packet)
620 {
621 struct nmb_packet *nmb;
622 struct nmb_packet *copy_nmb;
623 struct packet_struct *pkt_copy;
624
625 if(( pkt_copy = SMB_MALLOC_P(struct packet_struct)) == NULL) {
626 DEBUG(0,("copy_nmb_packet: malloc fail.\n"));
627 return NULL;
628 }
629
630 /* Structure copy of entire thing. */
631
632 *pkt_copy = *packet;
633
634 /* Ensure this copy is not locked. */
635 pkt_copy->locked = False;
636 pkt_copy->recv_fd = -1;
637 pkt_copy->send_fd = -1;
638
639 /* Ensure this copy has no resource records. */
640 nmb = &packet->packet.nmb;
641 copy_nmb = &pkt_copy->packet.nmb;
642
643 copy_nmb->answers = NULL;
644 copy_nmb->nsrecs = NULL;
645 copy_nmb->additional = NULL;
646
647 /* Now copy any resource records. */
648
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));
655 }
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));
662 }
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));
669 }
670
671 return pkt_copy;
672
673 free_and_exit:
674
675 SAFE_FREE(copy_nmb->answers);
676 SAFE_FREE(copy_nmb->nsrecs);
677 SAFE_FREE(copy_nmb->additional);
678 SAFE_FREE(pkt_copy);
679
680 DEBUG(0,("copy_nmb_packet: malloc fail in resource records.\n"));
681 return NULL;
682 }
683
684 /*******************************************************************
685 'Copy constructor' for a dgram packet.
686 ******************************************************************/
687
copy_dgram_packet(struct packet_struct * packet)688 static struct packet_struct *copy_dgram_packet(struct packet_struct *packet)
689 {
690 struct packet_struct *pkt_copy;
691
692 if(( pkt_copy = SMB_MALLOC_P(struct packet_struct)) == NULL) {
693 DEBUG(0,("copy_dgram_packet: malloc fail.\n"));
694 return NULL;
695 }
696
697 /* Structure copy of entire thing. */
698
699 *pkt_copy = *packet;
700
701 /* Ensure this copy is not locked. */
702 pkt_copy->locked = False;
703 pkt_copy->recv_fd = -1;
704 pkt_copy->send_fd = -1;
705
706 /* There are no additional pointers in a dgram packet,
707 we are finished. */
708 return pkt_copy;
709 }
710
711 /*******************************************************************
712 'Copy constructor' for a generic packet.
713 ******************************************************************/
714
copy_packet(struct packet_struct * packet)715 struct packet_struct *copy_packet(struct packet_struct *packet)
716 {
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;
722 }
723
724 /*******************************************************************
725 Free up any resources associated with an nmb packet.
726 ******************************************************************/
727
free_nmb_packet(struct nmb_packet * nmb)728 static void free_nmb_packet(struct nmb_packet *nmb)
729 {
730 SAFE_FREE(nmb->answers);
731 SAFE_FREE(nmb->nsrecs);
732 SAFE_FREE(nmb->additional);
733 }
734
735 /*******************************************************************
736 Free up any resources associated with a dgram packet.
737 ******************************************************************/
738
free_dgram_packet(struct dgram_packet * nmb)739 static void free_dgram_packet(struct dgram_packet *nmb)
740 {
741 /* We have nothing to do for a dgram packet. */
742 }
743
744 /*******************************************************************
745 Free up any resources associated with a packet.
746 ******************************************************************/
747
free_packet(struct packet_struct * packet)748 void free_packet(struct packet_struct *packet)
749 {
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);
758 }
759
packet_trn_id(struct packet_struct * p)760 int packet_trn_id(struct packet_struct *p)
761 {
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;
772 }
773 return result;
774 }
775
776 /*******************************************************************
777 Parse a packet buffer into a packet structure.
778 ******************************************************************/
779
parse_packet(char * buf,int length,enum packet_type packet_type,struct in_addr ip,int port)780 struct packet_struct *parse_packet(char *buf,int length,
781 enum packet_type packet_type,
782 struct in_addr ip,
783 int port)
784 {
785 struct packet_struct *p;
786 bool ok=False;
787
788 p = SMB_MALLOC_P(struct packet_struct);
789 if (!p)
790 return(NULL);
791
792 ZERO_STRUCTP(p); /* initialize for possible padding */
793
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;
801
802 switch (packet_type) {
803 case NMB_PACKET:
804 ok = parse_nmb(buf,length,&p->packet.nmb);
805 break;
806
807 case DGRAM_PACKET:
808 ok = parse_dgram(buf,length,&p->packet.dgram);
809 break;
810 }
811
812 if (!ok) {
813 free_packet(p);
814 return NULL;
815 }
816
817 return p;
818 }
819
copy_packet_talloc(TALLOC_CTX * mem_ctx,const struct packet_struct * src)820 static struct packet_struct *copy_packet_talloc(
821 TALLOC_CTX *mem_ctx, const struct packet_struct *src)
822 {
823 struct packet_struct *pkt;
824
825 pkt = talloc_memdup(mem_ctx, src, sizeof(struct packet_struct));
826 if (pkt == NULL) {
827 return NULL;
828 }
829 pkt->locked = false;
830 pkt->recv_fd = -1;
831 pkt->send_fd = -1;
832
833 if (src->packet_type == NMB_PACKET) {
834 const struct nmb_packet *nsrc = &src->packet.nmb;
835 struct nmb_packet *ndst = &pkt->packet.nmb;
836
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;
843 }
844 }
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;
851 }
852 }
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;
859 }
860 }
861 }
862
863 return pkt;
864
865 /*
866 * DGRAM packets have no substructures
867 */
868
869 fail:
870 TALLOC_FREE(pkt);
871 return NULL;
872 }
873
parse_packet_talloc(TALLOC_CTX * mem_ctx,char * buf,int length,enum packet_type packet_type,struct in_addr ip,int port)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)
879 {
880 struct packet_struct *pkt, *result;
881
882 pkt = parse_packet(buf, length, packet_type, ip, port);
883 if (pkt == NULL) {
884 return NULL;
885 }
886 result = copy_packet_talloc(mem_ctx, pkt);
887 free_packet(pkt);
888 return result;
889 }
890
891 /*******************************************************************
892 Send a udp packet on a already open socket.
893 ******************************************************************/
894
send_udp(int fd,char * buf,int len,struct in_addr ip,int port)895 static bool send_udp(int fd,char *buf,int len,struct in_addr ip,int port)
896 {
897 bool ret = False;
898 int i;
899 struct sockaddr_in sock_out;
900
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;
906
907 DEBUG( 5, ( "Sending a packet of len %d to (%s) on port %d\n",
908 len, inet_ntoa(ip), port ) );
909
910 /*
911 * Patch to fix asynch error notifications from Linux kernel.
912 */
913
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;
919 }
920
921 if (!ret)
922 DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n",
923 inet_ntoa(ip),port,strerror(errno)));
924
925 return(ret);
926 }
927
928 /*******************************************************************
929 Build a dgram packet ready for sending.
930 If buf == NULL this is a length calculation.
931 ******************************************************************/
932
build_dgram(char * buf,size_t len,struct dgram_packet * dgram)933 static int build_dgram(char *buf, size_t len, struct dgram_packet *dgram)
934 {
935 unsigned char *ubuf = (unsigned char *)buf;
936 int offset=0;
937
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);
950 }
951
952 offset = 14;
953
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);
959 }
960
961 if (buf) {
962 memcpy(ubuf+offset,dgram->data,dgram->datasize);
963 }
964 offset += dgram->datasize;
965
966 /* automatically set the dgm_length
967 * NOTE: RFC1002 says the dgm_length does *not*
968 * include the fourteen-byte header. crh
969 */
970 dgram->header.dgm_length = (offset - 14);
971 if (buf) {
972 RSSVAL(ubuf,10,dgram->header.dgm_length);
973 }
974
975 return offset;
976 }
977
978 /*******************************************************************
979 Build a nmb name
980 *******************************************************************/
981
make_nmb_name(struct nmb_name * n,const char * name,int type)982 void make_nmb_name( struct nmb_name *n, const char *name, int type)
983 {
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);
991 }
992
993 /*******************************************************************
994 Compare two nmb names
995 ******************************************************************/
996
nmb_name_equal(struct nmb_name * n1,struct nmb_name * n2)997 bool nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2)
998 {
999 return ((n1->name_type == n2->name_type) &&
1000 strequal(n1->name ,n2->name ) &&
1001 strequal(n1->scope,n2->scope));
1002 }
1003
1004 /*******************************************************************
1005 Build a nmb packet ready for sending.
1006 If buf == NULL this is a length calculation.
1007 ******************************************************************/
1008
build_nmb(char * buf,size_t len,struct nmb_packet * nmb)1009 static int build_nmb(char *buf, size_t len, struct nmb_packet *nmb)
1010 {
1011 unsigned char *ubuf = (unsigned char *)buf;
1012 int offset=0;
1013
1014 if (len && len < 12) {
1015 return 0;
1016 }
1017
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);
1037
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);
1042 }
1043
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;
1053 }
1054 }
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);
1060 }
1061 offset += 4;
1062 }
1063
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;
1071 }
1072 }
1073 offset += put_res_rec((char *)ubuf,len,offset,nmb->answers,
1074 nmb->header.ancount);
1075 }
1076
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;
1084 }
1085 }
1086 offset += put_res_rec((char *)ubuf,len,offset,nmb->nsrecs,
1087 nmb->header.nscount);
1088 }
1089
1090 /*
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.
1095 */
1096
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)) {
1104
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;
1111 }
1112 }
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;
1122 }
1123 }
1124 offset += put_res_rec((char *)ubuf,len,offset,nmb->additional,
1125 nmb->header.arcount);
1126 }
1127 return offset;
1128 }
1129
1130 /*******************************************************************
1131 Linearise a packet.
1132 ******************************************************************/
1133
build_packet(char * buf,size_t buflen,struct packet_struct * p)1134 int build_packet(char *buf, size_t buflen, struct packet_struct *p)
1135 {
1136 int len = 0;
1137
1138 switch (p->packet_type) {
1139 case NMB_PACKET:
1140 len = build_nmb(buf,buflen,&p->packet.nmb);
1141 break;
1142
1143 case DGRAM_PACKET:
1144 len = build_dgram(buf,buflen,&p->packet.dgram);
1145 break;
1146 }
1147
1148 return len;
1149 }
1150
1151 /*******************************************************************
1152 Send a packet_struct.
1153 ******************************************************************/
1154
send_packet(struct packet_struct * p)1155 bool send_packet(struct packet_struct *p)
1156 {
1157 char buf[1024];
1158 int len=0;
1159
1160 memset(buf,'\0',sizeof(buf));
1161
1162 len = build_packet(buf, sizeof(buf), p);
1163
1164 if (!len)
1165 return(False);
1166
1167 return(send_udp(p->send_fd,buf,len,p->ip,p->port));
1168 }
1169
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 ***************************************************************************/
1175
1176 /****************************************************************************
1177 See if a datagram has the right mailslot name.
1178 ***************************************************************************/
1179
match_mailslot_name(struct packet_struct * p,const char * mailslot_name)1180 bool match_mailslot_name(struct packet_struct *p, const char *mailslot_name)
1181 {
1182 struct dgram_packet *dgram = &p->packet.dgram;
1183 char *buf;
1184
1185 buf = &dgram->data[0];
1186 buf -= 4;
1187
1188 buf = smb_buf(buf);
1189
1190 if (memcmp(buf, mailslot_name, strlen(mailslot_name)+1) == 0) {
1191 return True;
1192 }
1193
1194 return False;
1195 }
1196
1197 /****************************************************************************
1198 Return the number of bits that match between two len character buffers
1199 ***************************************************************************/
1200
matching_len_bits(const unsigned char * p1,const unsigned char * p2,size_t len)1201 int matching_len_bits(const unsigned char *p1, const unsigned char *p2, size_t len)
1202 {
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;
1209 }
1210
1211 if (i==len)
1212 return ret;
1213
1214 for (j=0; j<8; j++) {
1215 if ((p1[i] & (1<<(7-j))) != (p2[i] & (1<<(7-j))))
1216 break;
1217 ret++;
1218 }
1219
1220 return ret;
1221 }
1222
1223 static unsigned char sort_ip[4];
1224
1225 /****************************************************************************
1226 Compare two query reply records.
1227 ***************************************************************************/
1228
name_query_comp(unsigned char * p1,unsigned char * p2)1229 static int name_query_comp(unsigned char *p1, unsigned char *p2)
1230 {
1231 return matching_len_bits(p2+2, sort_ip, 4) -
1232 matching_len_bits(p1+2, sort_ip, 4);
1233 }
1234
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 ***************************************************************************/
1239
sort_query_replies(char * data,int n,struct in_addr ip)1240 void sort_query_replies(char *data, int n, struct in_addr ip)
1241 {
1242 if (n <= 1)
1243 return;
1244
1245 putip(sort_ip, (char *)&ip);
1246
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*
1250 */
1251 qsort(data, n, 6, QSORT_CAST name_query_comp);
1252 }
1253
1254 /****************************************************************************
1255 Interpret the weird netbios "name" into a unix fstring. Return the name type.
1256 Returns -1 on error.
1257 ****************************************************************************/
1258
name_interpret(unsigned char * buf,size_t buf_len,unsigned char * in,fstring name)1259 static int name_interpret(unsigned char *buf, size_t buf_len,
1260 unsigned char *in, fstring name)
1261 {
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;
1267
1268 *out=0;
1269
1270 if (in >= end_ptr) {
1271 return -1;
1272 }
1273 len = (*in++) / 2;
1274
1275 if (len<1) {
1276 return -1;
1277 }
1278
1279 while (len--) {
1280 if (&in[1] >= end_ptr) {
1281 return -1;
1282 }
1283 if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
1284 *out = 0;
1285 return(0);
1286 }
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;
1292 }
1293 }
1294 ret = out[-1];
1295 out[-1] = 0;
1296
1297 pull_ascii_fstring(name, out_string);
1298
1299 return(ret);
1300 }
1301
1302 /****************************************************************************
1303 Mangle a name into netbios format.
1304 Note: <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
1305 ****************************************************************************/
1306
name_mangle(TALLOC_CTX * mem_ctx,const char * In,char name_type)1307 char *name_mangle(TALLOC_CTX *mem_ctx, const char *In, char name_type)
1308 {
1309 int i;
1310 int len;
1311 nstring buf;
1312 char *result;
1313 char *p;
1314
1315 result = talloc_array(mem_ctx, char, 33 + strlen(lp_netbios_scope()) + 2);
1316 if (result == NULL) {
1317 return NULL;
1318 }
1319 p = result;
1320
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;
1329
1330 pull_ascii_fstring(buf_unix, In);
1331 if (!strupper_m(buf_unix)) {
1332 return NULL;
1333 }
1334
1335 push_ascii_nstring(buf_dos, buf_unix);
1336 put_name(buf, buf_dos, ' ', name_type);
1337 }
1338
1339 /* Place the length of the first field into the output buffer. */
1340 p[0] = 32;
1341 p++;
1342
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';
1347 }
1348 p += 32;
1349 p[0] = '\0';
1350
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;
1367 }
1368 }
1369
1370 return result;
1371 }
1372
1373 /****************************************************************************
1374 Find a pointer to a netbios name.
1375 ****************************************************************************/
1376
name_ptr(unsigned char * buf,size_t buf_len,unsigned int ofs)1377 static unsigned char *name_ptr(unsigned char *buf, size_t buf_len, unsigned int ofs)
1378 {
1379 unsigned char c = 0;
1380
1381 if (ofs > buf_len || buf_len < 1) {
1382 return NULL;
1383 }
1384
1385 c = *(unsigned char *)(buf+ofs);
1386 if ((c & 0xC0) == 0xC0) {
1387 uint16_t l = 0;
1388
1389 if (ofs > buf_len - 1) {
1390 return NULL;
1391 }
1392 l = RSVAL(buf, ofs) & 0x3FFF;
1393 if (l > buf_len) {
1394 return NULL;
1395 }
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);
1400 }
1401 }
1402
1403 /****************************************************************************
1404 Extract a netbios name from a buf (into a unix string) return name type.
1405 Returns -1 on error.
1406 ****************************************************************************/
1407
name_extract(unsigned char * buf,size_t buf_len,unsigned int ofs,fstring name)1408 int name_extract(unsigned char *buf, size_t buf_len, unsigned int ofs, fstring name)
1409 {
1410 unsigned char *p = name_ptr(buf,buf_len,ofs);
1411
1412 name[0] = '\0';
1413 if (p == NULL) {
1414 return -1;
1415 }
1416 return(name_interpret(buf,buf_len,p,name));
1417 }
1418
1419 /****************************************************************************
1420 Return the total storage length of a mangled name.
1421 Returns -1 on error.
1422 ****************************************************************************/
1423
name_len(unsigned char * s1,size_t buf_len)1424 int name_len(unsigned char *s1, size_t buf_len)
1425 {
1426 /* NOTE: this argument _must_ be unsigned */
1427 unsigned char *s = (unsigned char *)s1;
1428 int len = 0;
1429
1430 if (buf_len < 1) {
1431 return -1;
1432 }
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;
1437 }
1438 return(2);
1439 }
1440
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;
1446 }
1447 }
1448
1449 return(len);
1450 }
1451