/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- lookup_opcode_name
- debug_nmb_res_rec
- debug_nmb_packet
- handle_name_ptrs
- parse_nmb_name
- put_name
- put_nmb_name
- nmb_namestr
- parse_alloc_res_rec
- put_res_rec
- put_compressed_name_ptr
- parse_dgram
- parse_nmb
- copy_nmb_packet
- copy_dgram_packet
- copy_packet
- free_nmb_packet
- free_dgram_packet
- free_packet
- parse_packet
- read_packet
- send_udp
- build_dgram
- make_nmb_name
- nmb_name_equal
- build_nmb
- build_packet
- send_packet
- receive_packet
- receive_nmb_packet
- receive_dgram_packet
- match_mailslot_name
- matching_len_bits
- name_query_comp
- sort_query_replies
- name_interpret
- name_mangle
- name_ptr
- name_extract
- name_len
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
24 static const struct opcode_names {
25 const char *nmb_opcode_name;
26 int opcode;
27 } nmb_header_opcode_names[] = {
28 {"Query", 0 },
29 {"Registration", 5 },
30 {"Release", 6 },
31 {"WACK", 7 },
32 {"Refresh", 8 },
33 {"Refresh(altcode)", 9 },
34 {"Multi-homed Registration", 15 },
35 {0, -1 }
36 };
37
38 /****************************************************************************
39 Lookup a nmb opcode name.
40 ****************************************************************************/
41
42 static const char *lookup_opcode_name( int opcode )
/* [<][>][^][v][top][bottom][index][help] */
43 {
44 const struct opcode_names *op_namep;
45 int i;
46
47 for(i = 0; nmb_header_opcode_names[i].nmb_opcode_name != 0; i++) {
48 op_namep = &nmb_header_opcode_names[i];
49 if(opcode == op_namep->opcode)
50 return op_namep->nmb_opcode_name;
51 }
52 return "<unknown opcode>";
53 }
54
55 /****************************************************************************
56 Print out a res_rec structure.
57 ****************************************************************************/
58
59 static void debug_nmb_res_rec(struct res_rec *res, const char *hdr)
/* [<][>][^][v][top][bottom][index][help] */
60 {
61 int i, j;
62
63 DEBUGADD( 4, ( " %s: nmb_name=%s rr_type=%d rr_class=%d ttl=%d\n",
64 hdr,
65 nmb_namestr(&res->rr_name),
66 res->rr_type,
67 res->rr_class,
68 res->ttl ) );
69
70 if( res->rdlength == 0 || res->rdata == NULL )
71 return;
72
73 for (i = 0; i < res->rdlength; i+= MAX_NETBIOSNAME_LEN) {
74 DEBUGADD(4, (" %s %3x char ", hdr, i));
75
76 for (j = 0; j < MAX_NETBIOSNAME_LEN; j++) {
77 unsigned char x = res->rdata[i+j];
78 if (x < 32 || x > 127)
79 x = '.';
80
81 if (i+j >= res->rdlength)
82 break;
83 DEBUGADD(4, ("%c", x));
84 }
85
86 DEBUGADD(4, (" hex "));
87
88 for (j = 0; j < MAX_NETBIOSNAME_LEN; j++) {
89 if (i+j >= res->rdlength)
90 break;
91 DEBUGADD(4, ("%02X", (unsigned char)res->rdata[i+j]));
92 }
93
94 DEBUGADD(4, ("\n"));
95 }
96 }
97
98 /****************************************************************************
99 Process a nmb packet.
100 ****************************************************************************/
101
102 void debug_nmb_packet(struct packet_struct *p)
/* [<][>][^][v][top][bottom][index][help] */
103 {
104 struct nmb_packet *nmb = &p->packet.nmb;
105
106 if( DEBUGLVL( 4 ) ) {
107 dbgtext( "nmb packet from %s(%d) header: id=%d "
108 "opcode=%s(%d) response=%s\n",
109 inet_ntoa(p->ip), p->port,
110 nmb->header.name_trn_id,
111 lookup_opcode_name(nmb->header.opcode),
112 nmb->header.opcode,
113 BOOLSTR(nmb->header.response) );
114 dbgtext( " header: flags: bcast=%s rec_avail=%s "
115 "rec_des=%s trunc=%s auth=%s\n",
116 BOOLSTR(nmb->header.nm_flags.bcast),
117 BOOLSTR(nmb->header.nm_flags.recursion_available),
118 BOOLSTR(nmb->header.nm_flags.recursion_desired),
119 BOOLSTR(nmb->header.nm_flags.trunc),
120 BOOLSTR(nmb->header.nm_flags.authoritative) );
121 dbgtext( " header: rcode=%d qdcount=%d ancount=%d "
122 "nscount=%d arcount=%d\n",
123 nmb->header.rcode,
124 nmb->header.qdcount,
125 nmb->header.ancount,
126 nmb->header.nscount,
127 nmb->header.arcount );
128 }
129
130 if (nmb->header.qdcount) {
131 DEBUGADD( 4, ( " question: q_name=%s q_type=%d q_class=%d\n",
132 nmb_namestr(&nmb->question.question_name),
133 nmb->question.question_type,
134 nmb->question.question_class) );
135 }
136
137 if (nmb->answers && nmb->header.ancount) {
138 debug_nmb_res_rec(nmb->answers,"answers");
139 }
140 if (nmb->nsrecs && nmb->header.nscount) {
141 debug_nmb_res_rec(nmb->nsrecs,"nsrecs");
142 }
143 if (nmb->additional && nmb->header.arcount) {
144 debug_nmb_res_rec(nmb->additional,"additional");
145 }
146 }
147
148 /*******************************************************************
149 Handle "compressed" name pointers.
150 ******************************************************************/
151
152 static bool handle_name_ptrs(unsigned char *ubuf,int *offset,int length,
/* [<][>][^][v][top][bottom][index][help] */
153 bool *got_pointer,int *ret)
154 {
155 int loop_count=0;
156
157 while ((ubuf[*offset] & 0xC0) == 0xC0) {
158 if (!*got_pointer)
159 (*ret) += 2;
160 (*got_pointer)=True;
161 (*offset) = ((ubuf[*offset] & ~0xC0)<<8) | ubuf[(*offset)+1];
162 if (loop_count++ == 10 ||
163 (*offset) < 0 || (*offset)>(length-2)) {
164 return False;
165 }
166 }
167 return True;
168 }
169
170 /*******************************************************************
171 Parse a nmb name from "compressed" format to something readable
172 return the space taken by the name, or 0 if the name is invalid
173 ******************************************************************/
174
175 static int parse_nmb_name(char *inbuf,int ofs,int length, struct nmb_name *name)
/* [<][>][^][v][top][bottom][index][help] */
176 {
177 int m,n=0;
178 unsigned char *ubuf = (unsigned char *)inbuf;
179 int ret = 0;
180 bool got_pointer=False;
181 int loop_count=0;
182 int offset = ofs;
183
184 if (length - offset < 2)
185 return(0);
186
187 /* handle initial name pointers */
188 if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret))
189 return(0);
190
191 m = ubuf[offset];
192
193 if (!m)
194 return(0);
195 if ((m & 0xC0) || offset+m+2 > length)
196 return(0);
197
198 memset((char *)name,'\0',sizeof(*name));
199
200 /* the "compressed" part */
201 if (!got_pointer)
202 ret += m + 2;
203 offset++;
204 while (m > 0) {
205 unsigned char c1,c2;
206 c1 = ubuf[offset++]-'A';
207 c2 = ubuf[offset++]-'A';
208 if ((c1 & 0xF0) || (c2 & 0xF0) || (n > sizeof(name->name)-1))
209 return(0);
210 name->name[n++] = (c1<<4) | c2;
211 m -= 2;
212 }
213 name->name[n] = 0;
214
215 if (n==MAX_NETBIOSNAME_LEN) {
216 /* parse out the name type, its always
217 * in the 16th byte of the name */
218 name->name_type = ((unsigned char)name->name[15]) & 0xff;
219
220 /* remove trailing spaces */
221 name->name[15] = 0;
222 n = 14;
223 while (n && name->name[n]==' ')
224 name->name[n--] = 0;
225 }
226
227 /* now the domain parts (if any) */
228 n = 0;
229 while (ubuf[offset]) {
230 /* we can have pointers within the domain part as well */
231 if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret))
232 return(0);
233
234 m = ubuf[offset];
235 /*
236 * Don't allow null domain parts.
237 */
238 if (!m)
239 return(0);
240 if (!got_pointer)
241 ret += m+1;
242 if (n)
243 name->scope[n++] = '.';
244 if (m+2+offset>length || n+m+1>sizeof(name->scope))
245 return(0);
246 offset++;
247 while (m--)
248 name->scope[n++] = (char)ubuf[offset++];
249
250 /*
251 * Watch for malicious loops.
252 */
253 if (loop_count++ == 10)
254 return 0;
255 }
256 name->scope[n++] = 0;
257
258 return(ret);
259 }
260
261 /****************************************************************************
262 Put a netbios name, padding(s) and a name type into a 16 character buffer.
263 name is already in DOS charset.
264 [15 bytes name + padding][1 byte name type].
265 ****************************************************************************/
266
267 void put_name(char *dest, const char *name, int pad, unsigned int name_type)
/* [<][>][^][v][top][bottom][index][help] */
268 {
269 size_t len = strlen(name);
270
271 memcpy(dest, name, (len < MAX_NETBIOSNAME_LEN) ?
272 len : MAX_NETBIOSNAME_LEN - 1);
273 if (len < MAX_NETBIOSNAME_LEN - 1) {
274 memset(dest + len, pad, MAX_NETBIOSNAME_LEN - 1 - len);
275 }
276 dest[MAX_NETBIOSNAME_LEN - 1] = name_type;
277 }
278
279 /*******************************************************************
280 Put a compressed nmb name into a buffer. Return the length of the
281 compressed name.
282
283 Compressed names are really weird. The "compression" doubles the
284 size. The idea is that it also means that compressed names conform
285 to the doman name system. See RFC1002.
286
287 If buf == NULL this is a length calculation.
288 ******************************************************************/
289
290 static int put_nmb_name(char *buf,int offset,struct nmb_name *name)
/* [<][>][^][v][top][bottom][index][help] */
291 {
292 int ret,m;
293 nstring buf1;
294 char *p;
295
296 if (strcmp(name->name,"*") == 0) {
297 /* special case for wildcard name */
298 put_name(buf1, "*", '\0', name->name_type);
299 } else {
300 put_name(buf1, name->name, ' ', name->name_type);
301 }
302
303 if (buf) {
304 buf[offset] = 0x20;
305 }
306
307 ret = 34;
308
309 for (m=0;m<MAX_NETBIOSNAME_LEN;m++) {
310 if (buf) {
311 buf[offset+1+2*m] = 'A' + ((buf1[m]>>4)&0xF);
312 buf[offset+2+2*m] = 'A' + (buf1[m]&0xF);
313 }
314 }
315 offset += 33;
316
317 if (buf) {
318 buf[offset] = 0;
319 }
320
321 if (name->scope[0]) {
322 /* XXXX this scope handling needs testing */
323 ret += strlen(name->scope) + 1;
324 if (buf) {
325 safe_strcpy(&buf[offset+1],name->scope,
326 sizeof(name->scope));
327
328 p = &buf[offset+1];
329 while ((p = strchr_m(p,'.'))) {
330 buf[offset] = PTR_DIFF(p,&buf[offset+1]);
331 offset += (buf[offset] + 1);
332 p = &buf[offset+1];
333 }
334 buf[offset] = strlen(&buf[offset+1]);
335 }
336 }
337
338 return ret;
339 }
340
341 /*******************************************************************
342 Useful for debugging messages.
343 ******************************************************************/
344
345 char *nmb_namestr(const struct nmb_name *n)
/* [<][>][^][v][top][bottom][index][help] */
346 {
347 fstring name;
348 char *result;
349
350 pull_ascii_fstring(name, n->name);
351 if (!n->scope[0])
352 result = talloc_asprintf(talloc_tos(), "%s<%02x>", name,
353 n->name_type);
354 else
355 result = talloc_asprintf(talloc_tos(), "%s<%02x>.%s", name,
356 n->name_type, n->scope);
357
358 SMB_ASSERT(result != NULL);
359 return result;
360 }
361
362 /*******************************************************************
363 Allocate and parse some resource records.
364 ******************************************************************/
365
366 static bool parse_alloc_res_rec(char *inbuf,int *offset,int length,
/* [<][>][^][v][top][bottom][index][help] */
367 struct res_rec **recs, int count)
368 {
369 int i;
370
371 *recs = SMB_MALLOC_ARRAY(struct res_rec, count);
372 if (!*recs)
373 return(False);
374
375 memset((char *)*recs,'\0',sizeof(**recs)*count);
376
377 for (i=0;i<count;i++) {
378 int l = parse_nmb_name(inbuf,*offset,length,
379 &(*recs)[i].rr_name);
380 (*offset) += l;
381 if (!l || (*offset)+10 > length) {
382 SAFE_FREE(*recs);
383 return(False);
384 }
385 (*recs)[i].rr_type = RSVAL(inbuf,(*offset));
386 (*recs)[i].rr_class = RSVAL(inbuf,(*offset)+2);
387 (*recs)[i].ttl = RIVAL(inbuf,(*offset)+4);
388 (*recs)[i].rdlength = RSVAL(inbuf,(*offset)+8);
389 (*offset) += 10;
390 if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) ||
391 (*offset)+(*recs)[i].rdlength > length) {
392 SAFE_FREE(*recs);
393 return(False);
394 }
395 memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength);
396 (*offset) += (*recs)[i].rdlength;
397 }
398 return(True);
399 }
400
401 /*******************************************************************
402 Put a resource record into a packet.
403 If buf == NULL this is a length calculation.
404 ******************************************************************/
405
406 static int put_res_rec(char *buf,int offset,struct res_rec *recs,int count)
/* [<][>][^][v][top][bottom][index][help] */
407 {
408 int ret=0;
409 int i;
410
411 for (i=0;i<count;i++) {
412 int l = put_nmb_name(buf,offset,&recs[i].rr_name);
413 offset += l;
414 ret += l;
415 if (buf) {
416 RSSVAL(buf,offset,recs[i].rr_type);
417 RSSVAL(buf,offset+2,recs[i].rr_class);
418 RSIVAL(buf,offset+4,recs[i].ttl);
419 RSSVAL(buf,offset+8,recs[i].rdlength);
420 memcpy(buf+offset+10,recs[i].rdata,recs[i].rdlength);
421 }
422 offset += 10+recs[i].rdlength;
423 ret += 10+recs[i].rdlength;
424 }
425
426 return ret;
427 }
428
429 /*******************************************************************
430 Put a compressed name pointer record into a packet.
431 If buf == NULL this is a length calculation.
432 ******************************************************************/
433
434 static int put_compressed_name_ptr(unsigned char *buf,
/* [<][>][^][v][top][bottom][index][help] */
435 int offset,
436 struct res_rec *rec,
437 int ptr_offset)
438 {
439 int ret=0;
440 if (buf) {
441 buf[offset] = (0xC0 | ((ptr_offset >> 8) & 0xFF));
442 buf[offset+1] = (ptr_offset & 0xFF);
443 }
444 offset += 2;
445 ret += 2;
446 if (buf) {
447 RSSVAL(buf,offset,rec->rr_type);
448 RSSVAL(buf,offset+2,rec->rr_class);
449 RSIVAL(buf,offset+4,rec->ttl);
450 RSSVAL(buf,offset+8,rec->rdlength);
451 memcpy(buf+offset+10,rec->rdata,rec->rdlength);
452 }
453 offset += 10+rec->rdlength;
454 ret += 10+rec->rdlength;
455
456 return ret;
457 }
458
459 /*******************************************************************
460 Parse a dgram packet. Return False if the packet can't be parsed
461 or is invalid for some reason, True otherwise.
462
463 This is documented in section 4.4.1 of RFC1002.
464 ******************************************************************/
465
466 static bool parse_dgram(char *inbuf,int length,struct dgram_packet *dgram)
/* [<][>][^][v][top][bottom][index][help] */
467 {
468 int offset;
469 int flags;
470
471 memset((char *)dgram,'\0',sizeof(*dgram));
472
473 if (length < 14)
474 return(False);
475
476 dgram->header.msg_type = CVAL(inbuf,0);
477 flags = CVAL(inbuf,1);
478 dgram->header.flags.node_type = (enum node_type)((flags>>2)&3);
479 if (flags & 1)
480 dgram->header.flags.more = True;
481 if (flags & 2)
482 dgram->header.flags.first = True;
483 dgram->header.dgm_id = RSVAL(inbuf,2);
484 putip((char *)&dgram->header.source_ip,inbuf+4);
485 dgram->header.source_port = RSVAL(inbuf,8);
486 dgram->header.dgm_length = RSVAL(inbuf,10);
487 dgram->header.packet_offset = RSVAL(inbuf,12);
488
489 offset = 14;
490
491 if (dgram->header.msg_type == 0x10 ||
492 dgram->header.msg_type == 0x11 ||
493 dgram->header.msg_type == 0x12) {
494 offset += parse_nmb_name(inbuf,offset,length,
495 &dgram->source_name);
496 offset += parse_nmb_name(inbuf,offset,length,
497 &dgram->dest_name);
498 }
499
500 if (offset >= length || (length-offset > sizeof(dgram->data)))
501 return(False);
502
503 dgram->datasize = length-offset;
504 memcpy(dgram->data,inbuf+offset,dgram->datasize);
505
506 /* Paranioa. Ensure the last 2 bytes in the dgram buffer are
507 zero. This should be true anyway, just enforce it for
508 paranioa sake. JRA. */
509 SMB_ASSERT(dgram->datasize <= (sizeof(dgram->data)-2));
510 memset(&dgram->data[sizeof(dgram->data)-2], '\0', 2);
511
512 return(True);
513 }
514
515 /*******************************************************************
516 Parse a nmb packet. Return False if the packet can't be parsed
517 or is invalid for some reason, True otherwise.
518 ******************************************************************/
519
520 static bool parse_nmb(char *inbuf,int length,struct nmb_packet *nmb)
/* [<][>][^][v][top][bottom][index][help] */
521 {
522 int nm_flags,offset;
523
524 memset((char *)nmb,'\0',sizeof(*nmb));
525
526 if (length < 12)
527 return(False);
528
529 /* parse the header */
530 nmb->header.name_trn_id = RSVAL(inbuf,0);
531
532 DEBUG(10,("parse_nmb: packet id = %d\n", nmb->header.name_trn_id));
533
534 nmb->header.opcode = (CVAL(inbuf,2) >> 3) & 0xF;
535 nmb->header.response = ((CVAL(inbuf,2)>>7)&1)?True:False;
536 nm_flags = ((CVAL(inbuf,2) & 0x7) << 4) + (CVAL(inbuf,3)>>4);
537 nmb->header.nm_flags.bcast = (nm_flags&1)?True:False;
538 nmb->header.nm_flags.recursion_available = (nm_flags&8)?True:False;
539 nmb->header.nm_flags.recursion_desired = (nm_flags&0x10)?True:False;
540 nmb->header.nm_flags.trunc = (nm_flags&0x20)?True:False;
541 nmb->header.nm_flags.authoritative = (nm_flags&0x40)?True:False;
542 nmb->header.rcode = CVAL(inbuf,3) & 0xF;
543 nmb->header.qdcount = RSVAL(inbuf,4);
544 nmb->header.ancount = RSVAL(inbuf,6);
545 nmb->header.nscount = RSVAL(inbuf,8);
546 nmb->header.arcount = RSVAL(inbuf,10);
547
548 if (nmb->header.qdcount) {
549 offset = parse_nmb_name(inbuf,12,length,
550 &nmb->question.question_name);
551 if (!offset)
552 return(False);
553
554 if (length - (12+offset) < 4)
555 return(False);
556 nmb->question.question_type = RSVAL(inbuf,12+offset);
557 nmb->question.question_class = RSVAL(inbuf,12+offset+2);
558
559 offset += 12+4;
560 } else {
561 offset = 12;
562 }
563
564 /* and any resource records */
565 if (nmb->header.ancount &&
566 !parse_alloc_res_rec(inbuf,&offset,length,&nmb->answers,
567 nmb->header.ancount))
568 return(False);
569
570 if (nmb->header.nscount &&
571 !parse_alloc_res_rec(inbuf,&offset,length,&nmb->nsrecs,
572 nmb->header.nscount))
573 return(False);
574
575 if (nmb->header.arcount &&
576 !parse_alloc_res_rec(inbuf,&offset,length,
577 &nmb->additional, nmb->header.arcount))
578 return(False);
579
580 return(True);
581 }
582
583 /*******************************************************************
584 'Copy constructor' for an nmb packet.
585 ******************************************************************/
586
587 static struct packet_struct *copy_nmb_packet(struct packet_struct *packet)
/* [<][>][^][v][top][bottom][index][help] */
588 {
589 struct nmb_packet *nmb;
590 struct nmb_packet *copy_nmb;
591 struct packet_struct *pkt_copy;
592
593 if(( pkt_copy = SMB_MALLOC_P(struct packet_struct)) == NULL) {
594 DEBUG(0,("copy_nmb_packet: malloc fail.\n"));
595 return NULL;
596 }
597
598 /* Structure copy of entire thing. */
599
600 *pkt_copy = *packet;
601
602 /* Ensure this copy is not locked. */
603 pkt_copy->locked = False;
604
605 /* Ensure this copy has no resource records. */
606 nmb = &packet->packet.nmb;
607 copy_nmb = &pkt_copy->packet.nmb;
608
609 copy_nmb->answers = NULL;
610 copy_nmb->nsrecs = NULL;
611 copy_nmb->additional = NULL;
612
613 /* Now copy any resource records. */
614
615 if (nmb->answers) {
616 if((copy_nmb->answers = SMB_MALLOC_ARRAY(
617 struct res_rec,nmb->header.ancount)) == NULL)
618 goto free_and_exit;
619 memcpy((char *)copy_nmb->answers, (char *)nmb->answers,
620 nmb->header.ancount * sizeof(struct res_rec));
621 }
622 if (nmb->nsrecs) {
623 if((copy_nmb->nsrecs = SMB_MALLOC_ARRAY(
624 struct res_rec, nmb->header.nscount)) == NULL)
625 goto free_and_exit;
626 memcpy((char *)copy_nmb->nsrecs, (char *)nmb->nsrecs,
627 nmb->header.nscount * sizeof(struct res_rec));
628 }
629 if (nmb->additional) {
630 if((copy_nmb->additional = SMB_MALLOC_ARRAY(
631 struct res_rec, nmb->header.arcount)) == NULL)
632 goto free_and_exit;
633 memcpy((char *)copy_nmb->additional, (char *)nmb->additional,
634 nmb->header.arcount * sizeof(struct res_rec));
635 }
636
637 return pkt_copy;
638
639 free_and_exit:
640
641 SAFE_FREE(copy_nmb->answers);
642 SAFE_FREE(copy_nmb->nsrecs);
643 SAFE_FREE(copy_nmb->additional);
644 SAFE_FREE(pkt_copy);
645
646 DEBUG(0,("copy_nmb_packet: malloc fail in resource records.\n"));
647 return NULL;
648 }
649
650 /*******************************************************************
651 'Copy constructor' for a dgram packet.
652 ******************************************************************/
653
654 static struct packet_struct *copy_dgram_packet(struct packet_struct *packet)
/* [<][>][^][v][top][bottom][index][help] */
655 {
656 struct packet_struct *pkt_copy;
657
658 if(( pkt_copy = SMB_MALLOC_P(struct packet_struct)) == NULL) {
659 DEBUG(0,("copy_dgram_packet: malloc fail.\n"));
660 return NULL;
661 }
662
663 /* Structure copy of entire thing. */
664
665 *pkt_copy = *packet;
666
667 /* Ensure this copy is not locked. */
668 pkt_copy->locked = False;
669
670 /* There are no additional pointers in a dgram packet,
671 we are finished. */
672 return pkt_copy;
673 }
674
675 /*******************************************************************
676 'Copy constructor' for a generic packet.
677 ******************************************************************/
678
679 struct packet_struct *copy_packet(struct packet_struct *packet)
/* [<][>][^][v][top][bottom][index][help] */
680 {
681 if(packet->packet_type == NMB_PACKET)
682 return copy_nmb_packet(packet);
683 else if (packet->packet_type == DGRAM_PACKET)
684 return copy_dgram_packet(packet);
685 return NULL;
686 }
687
688 /*******************************************************************
689 Free up any resources associated with an nmb packet.
690 ******************************************************************/
691
692 static void free_nmb_packet(struct nmb_packet *nmb)
/* [<][>][^][v][top][bottom][index][help] */
693 {
694 SAFE_FREE(nmb->answers);
695 SAFE_FREE(nmb->nsrecs);
696 SAFE_FREE(nmb->additional);
697 }
698
699 /*******************************************************************
700 Free up any resources associated with a dgram packet.
701 ******************************************************************/
702
703 static void free_dgram_packet(struct dgram_packet *nmb)
/* [<][>][^][v][top][bottom][index][help] */
704 {
705 /* We have nothing to do for a dgram packet. */
706 }
707
708 /*******************************************************************
709 Free up any resources associated with a packet.
710 ******************************************************************/
711
712 void free_packet(struct packet_struct *packet)
/* [<][>][^][v][top][bottom][index][help] */
713 {
714 if (packet->locked)
715 return;
716 if (packet->packet_type == NMB_PACKET)
717 free_nmb_packet(&packet->packet.nmb);
718 else if (packet->packet_type == DGRAM_PACKET)
719 free_dgram_packet(&packet->packet.dgram);
720 ZERO_STRUCTPN(packet);
721 SAFE_FREE(packet);
722 }
723
724 /*******************************************************************
725 Parse a packet buffer into a packet structure.
726 ******************************************************************/
727
728 struct packet_struct *parse_packet(char *buf,int length,
/* [<][>][^][v][top][bottom][index][help] */
729 enum packet_type packet_type,
730 struct in_addr ip,
731 int port)
732 {
733 struct packet_struct *p;
734 bool ok=False;
735
736 p = SMB_MALLOC_P(struct packet_struct);
737 if (!p)
738 return(NULL);
739
740 ZERO_STRUCTP(p); /* initialize for possible padding */
741
742 p->next = NULL;
743 p->prev = NULL;
744 p->ip = ip;
745 p->port = port;
746 p->locked = False;
747 p->timestamp = time(NULL);
748 p->packet_type = packet_type;
749
750 switch (packet_type) {
751 case NMB_PACKET:
752 ok = parse_nmb(buf,length,&p->packet.nmb);
753 break;
754
755 case DGRAM_PACKET:
756 ok = parse_dgram(buf,length,&p->packet.dgram);
757 break;
758 }
759
760 if (!ok) {
761 free_packet(p);
762 return NULL;
763 }
764
765 return p;
766 }
767
768 /*******************************************************************
769 Read a packet from a socket and parse it, returning a packet ready
770 to be used or put on the queue. This assumes a UDP socket.
771 ******************************************************************/
772
773 struct packet_struct *read_packet(int fd,enum packet_type packet_type)
/* [<][>][^][v][top][bottom][index][help] */
774 {
775 struct packet_struct *packet;
776 struct sockaddr_storage sa;
777 struct sockaddr_in *si = (struct sockaddr_in *)&sa;
778 char buf[MAX_DGRAM_SIZE];
779 int length;
780
781 length = read_udp_v4_socket(fd,buf,sizeof(buf),&sa);
782 if (length < MIN_DGRAM_SIZE || sa.ss_family != AF_INET) {
783 return NULL;
784 }
785
786 packet = parse_packet(buf,
787 length,
788 packet_type,
789 si->sin_addr,
790 ntohs(si->sin_port));
791 if (!packet)
792 return NULL;
793
794 packet->fd = fd;
795
796 DEBUG(5,("Received a packet of len %d from (%s) port %d\n",
797 length, inet_ntoa(packet->ip), packet->port ) );
798
799 return(packet);
800 }
801
802 /*******************************************************************
803 Send a udp packet on a already open socket.
804 ******************************************************************/
805
806 static bool send_udp(int fd,char *buf,int len,struct in_addr ip,int port)
/* [<][>][^][v][top][bottom][index][help] */
807 {
808 bool ret = False;
809 int i;
810 struct sockaddr_in sock_out;
811
812 /* set the address and port */
813 memset((char *)&sock_out,'\0',sizeof(sock_out));
814 putip((char *)&sock_out.sin_addr,(char *)&ip);
815 sock_out.sin_port = htons( port );
816 sock_out.sin_family = AF_INET;
817
818 DEBUG( 5, ( "Sending a packet of len %d to (%s) on port %d\n",
819 len, inet_ntoa(ip), port ) );
820
821 /*
822 * Patch to fix asynch error notifications from Linux kernel.
823 */
824
825 for (i = 0; i < 5; i++) {
826 ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out,
827 sizeof(sock_out)) >= 0);
828 if (ret || errno != ECONNREFUSED)
829 break;
830 }
831
832 if (!ret)
833 DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n",
834 inet_ntoa(ip),port,strerror(errno)));
835
836 return(ret);
837 }
838
839 /*******************************************************************
840 Build a dgram packet ready for sending.
841 If buf == NULL this is a length calculation.
842 ******************************************************************/
843
844 static int build_dgram(char *buf, size_t len, struct dgram_packet *dgram)
/* [<][>][^][v][top][bottom][index][help] */
845 {
846 unsigned char *ubuf = (unsigned char *)buf;
847 int offset=0;
848
849 /* put in the header */
850 if (buf) {
851 ubuf[0] = dgram->header.msg_type;
852 ubuf[1] = (((int)dgram->header.flags.node_type)<<2);
853 if (dgram->header.flags.more)
854 ubuf[1] |= 1;
855 if (dgram->header.flags.first)
856 ubuf[1] |= 2;
857 RSSVAL(ubuf,2,dgram->header.dgm_id);
858 putip(ubuf+4,(char *)&dgram->header.source_ip);
859 RSSVAL(ubuf,8,dgram->header.source_port);
860 RSSVAL(ubuf,12,dgram->header.packet_offset);
861 }
862
863 offset = 14;
864
865 if (dgram->header.msg_type == 0x10 ||
866 dgram->header.msg_type == 0x11 ||
867 dgram->header.msg_type == 0x12) {
868 offset += put_nmb_name((char *)ubuf,offset,&dgram->source_name);
869 offset += put_nmb_name((char *)ubuf,offset,&dgram->dest_name);
870 }
871
872 if (buf) {
873 memcpy(ubuf+offset,dgram->data,dgram->datasize);
874 }
875 offset += dgram->datasize;
876
877 /* automatically set the dgm_length
878 * NOTE: RFC1002 says the dgm_length does *not*
879 * include the fourteen-byte header. crh
880 */
881 dgram->header.dgm_length = (offset - 14);
882 if (buf) {
883 RSSVAL(ubuf,10,dgram->header.dgm_length);
884 }
885
886 return offset;
887 }
888
889 /*******************************************************************
890 Build a nmb name
891 *******************************************************************/
892
893 void make_nmb_name( struct nmb_name *n, const char *name, int type)
/* [<][>][^][v][top][bottom][index][help] */
894 {
895 fstring unix_name;
896 memset( (char *)n, '\0', sizeof(struct nmb_name) );
897 fstrcpy(unix_name, name);
898 strupper_m(unix_name);
899 push_ascii(n->name, unix_name, sizeof(n->name), STR_TERMINATE);
900 n->name_type = (unsigned int)type & 0xFF;
901 push_ascii(n->scope, global_scope(), 64, STR_TERMINATE);
902 }
903
904 /*******************************************************************
905 Compare two nmb names
906 ******************************************************************/
907
908 bool nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2)
/* [<][>][^][v][top][bottom][index][help] */
909 {
910 return ((n1->name_type == n2->name_type) &&
911 strequal(n1->name ,n2->name ) &&
912 strequal(n1->scope,n2->scope));
913 }
914
915 /*******************************************************************
916 Build a nmb packet ready for sending.
917 If buf == NULL this is a length calculation.
918 ******************************************************************/
919
920 static int build_nmb(char *buf, size_t len, struct nmb_packet *nmb)
/* [<][>][^][v][top][bottom][index][help] */
921 {
922 unsigned char *ubuf = (unsigned char *)buf;
923 int offset=0;
924
925 if (len && len < 12) {
926 return 0;
927 }
928
929 /* put in the header */
930 if (buf) {
931 RSSVAL(ubuf,offset,nmb->header.name_trn_id);
932 ubuf[offset+2] = (nmb->header.opcode & 0xF) << 3;
933 if (nmb->header.response)
934 ubuf[offset+2] |= (1<<7);
935 if (nmb->header.nm_flags.authoritative &&
936 nmb->header.response)
937 ubuf[offset+2] |= 0x4;
938 if (nmb->header.nm_flags.trunc)
939 ubuf[offset+2] |= 0x2;
940 if (nmb->header.nm_flags.recursion_desired)
941 ubuf[offset+2] |= 0x1;
942 if (nmb->header.nm_flags.recursion_available &&
943 nmb->header.response)
944 ubuf[offset+3] |= 0x80;
945 if (nmb->header.nm_flags.bcast)
946 ubuf[offset+3] |= 0x10;
947 ubuf[offset+3] |= (nmb->header.rcode & 0xF);
948
949 RSSVAL(ubuf,offset+4,nmb->header.qdcount);
950 RSSVAL(ubuf,offset+6,nmb->header.ancount);
951 RSSVAL(ubuf,offset+8,nmb->header.nscount);
952 RSSVAL(ubuf,offset+10,nmb->header.arcount);
953 }
954
955 offset += 12;
956 if (nmb->header.qdcount) {
957 /* XXXX this doesn't handle a qdcount of > 1 */
958 if (len) {
959 /* Length check. */
960 int extra = put_nmb_name(NULL,offset,
961 &nmb->question.question_name);
962 if (offset + extra > len) {
963 return 0;
964 }
965 }
966 offset += put_nmb_name((char *)ubuf,offset,
967 &nmb->question.question_name);
968 if (buf) {
969 RSSVAL(ubuf,offset,nmb->question.question_type);
970 RSSVAL(ubuf,offset+2,nmb->question.question_class);
971 }
972 offset += 4;
973 }
974
975 if (nmb->header.ancount) {
976 if (len) {
977 /* Length check. */
978 int extra = put_res_rec(NULL,offset,nmb->answers,
979 nmb->header.ancount);
980 if (offset + extra > len) {
981 return 0;
982 }
983 }
984 offset += put_res_rec((char *)ubuf,offset,nmb->answers,
985 nmb->header.ancount);
986 }
987
988 if (nmb->header.nscount) {
989 if (len) {
990 /* Length check. */
991 int extra = put_res_rec(NULL,offset,nmb->nsrecs,
992 nmb->header.nscount);
993 if (offset + extra > len) {
994 return 0;
995 }
996 }
997 offset += put_res_rec((char *)ubuf,offset,nmb->nsrecs,
998 nmb->header.nscount);
999 }
1000
1001 /*
1002 * The spec says we must put compressed name pointers
1003 * in the following outgoing packets :
1004 * NAME_REGISTRATION_REQUEST, NAME_REFRESH_REQUEST,
1005 * NAME_RELEASE_REQUEST.
1006 */
1007
1008 if((nmb->header.response == False) &&
1009 ((nmb->header.opcode == NMB_NAME_REG_OPCODE) ||
1010 (nmb->header.opcode == NMB_NAME_RELEASE_OPCODE) ||
1011 (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_8) ||
1012 (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_9) ||
1013 (nmb->header.opcode == NMB_NAME_MULTIHOMED_REG_OPCODE)) &&
1014 (nmb->header.arcount == 1)) {
1015
1016 if (len) {
1017 /* Length check. */
1018 int extra = put_compressed_name_ptr(NULL,offset,
1019 nmb->additional,12);
1020 if (offset + extra > len) {
1021 return 0;
1022 }
1023 }
1024 offset += put_compressed_name_ptr(ubuf,offset,
1025 nmb->additional,12);
1026 } else if (nmb->header.arcount) {
1027 if (len) {
1028 /* Length check. */
1029 int extra = put_res_rec(NULL,offset,nmb->additional,
1030 nmb->header.arcount);
1031 if (offset + extra > len) {
1032 return 0;
1033 }
1034 }
1035 offset += put_res_rec((char *)ubuf,offset,nmb->additional,
1036 nmb->header.arcount);
1037 }
1038 return offset;
1039 }
1040
1041 /*******************************************************************
1042 Linearise a packet.
1043 ******************************************************************/
1044
1045 int build_packet(char *buf, size_t buflen, struct packet_struct *p)
/* [<][>][^][v][top][bottom][index][help] */
1046 {
1047 int len = 0;
1048
1049 switch (p->packet_type) {
1050 case NMB_PACKET:
1051 len = build_nmb(buf,buflen,&p->packet.nmb);
1052 break;
1053
1054 case DGRAM_PACKET:
1055 len = build_dgram(buf,buflen,&p->packet.dgram);
1056 break;
1057 }
1058
1059 return len;
1060 }
1061
1062 /*******************************************************************
1063 Send a packet_struct.
1064 ******************************************************************/
1065
1066 bool send_packet(struct packet_struct *p)
/* [<][>][^][v][top][bottom][index][help] */
1067 {
1068 char buf[1024];
1069 int len=0;
1070
1071 memset(buf,'\0',sizeof(buf));
1072
1073 len = build_packet(buf, sizeof(buf), p);
1074
1075 if (!len)
1076 return(False);
1077
1078 return(send_udp(p->fd,buf,len,p->ip,p->port));
1079 }
1080
1081 /****************************************************************************
1082 Receive a packet with timeout on a open UDP filedescriptor.
1083 The timeout is in milliseconds
1084 ***************************************************************************/
1085
1086 struct packet_struct *receive_packet(int fd,enum packet_type type,int t)
/* [<][>][^][v][top][bottom][index][help] */
1087 {
1088 fd_set fds;
1089 struct timeval timeout;
1090 int ret;
1091
1092 FD_ZERO(&fds);
1093 FD_SET(fd,&fds);
1094 timeout.tv_sec = t/1000;
1095 timeout.tv_usec = 1000*(t%1000);
1096
1097 if ((ret = sys_select_intr(fd+1,&fds,NULL,NULL,&timeout)) == -1) {
1098 /* errno should be EBADF or EINVAL. */
1099 DEBUG(0,("select returned -1, errno = %s (%d)\n",
1100 strerror(errno), errno));
1101 return NULL;
1102 }
1103
1104 if (ret == 0) /* timeout */
1105 return NULL;
1106
1107 if (FD_ISSET(fd,&fds))
1108 return(read_packet(fd,type));
1109
1110 return(NULL);
1111 }
1112
1113 /****************************************************************************
1114 Receive a UDP/137 packet either via UDP or from the unexpected packet
1115 queue. The packet must be a reply packet and have the specified trn_id.
1116 The timeout is in milliseconds.
1117 ***************************************************************************/
1118
1119 struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id)
/* [<][>][^][v][top][bottom][index][help] */
1120 {
1121 struct packet_struct *p;
1122
1123 p = receive_packet(fd, NMB_PACKET, t);
1124
1125 if (p && p->packet.nmb.header.response &&
1126 p->packet.nmb.header.name_trn_id == trn_id) {
1127 return p;
1128 }
1129 if (p)
1130 free_packet(p);
1131
1132 /* try the unexpected packet queue */
1133 return receive_unexpected(NMB_PACKET, trn_id, NULL);
1134 }
1135
1136 /****************************************************************************
1137 Receive a UDP/138 packet either via UDP or from the unexpected packet
1138 queue. The packet must be a reply packet and have the specified mailslot name
1139 The timeout is in milliseconds.
1140 ***************************************************************************/
1141
1142 struct packet_struct *receive_dgram_packet(int fd, int t,
/* [<][>][^][v][top][bottom][index][help] */
1143 const char *mailslot_name)
1144 {
1145 struct packet_struct *p;
1146
1147 p = receive_packet(fd, DGRAM_PACKET, t);
1148
1149 if (p && match_mailslot_name(p, mailslot_name)) {
1150 return p;
1151 }
1152 if (p)
1153 free_packet(p);
1154
1155 /* try the unexpected packet queue */
1156 return receive_unexpected(DGRAM_PACKET, 0, mailslot_name);
1157 }
1158
1159 /****************************************************************************
1160 See if a datagram has the right mailslot name.
1161 ***************************************************************************/
1162
1163 bool match_mailslot_name(struct packet_struct *p, const char *mailslot_name)
/* [<][>][^][v][top][bottom][index][help] */
1164 {
1165 struct dgram_packet *dgram = &p->packet.dgram;
1166 char *buf;
1167
1168 buf = &dgram->data[0];
1169 buf -= 4;
1170
1171 buf = smb_buf(buf);
1172
1173 if (memcmp(buf, mailslot_name, strlen(mailslot_name)+1) == 0) {
1174 return True;
1175 }
1176
1177 return False;
1178 }
1179
1180 /****************************************************************************
1181 Return the number of bits that match between two len character buffers
1182 ***************************************************************************/
1183
1184 int matching_len_bits(unsigned char *p1, unsigned char *p2, size_t len)
/* [<][>][^][v][top][bottom][index][help] */
1185 {
1186 size_t i, j;
1187 int ret = 0;
1188 for (i=0; i<len; i++) {
1189 if (p1[i] != p2[i])
1190 break;
1191 ret += 8;
1192 }
1193
1194 if (i==len)
1195 return ret;
1196
1197 for (j=0; j<8; j++) {
1198 if ((p1[i] & (1<<(7-j))) != (p2[i] & (1<<(7-j))))
1199 break;
1200 ret++;
1201 }
1202
1203 return ret;
1204 }
1205
1206 static unsigned char sort_ip[4];
1207
1208 /****************************************************************************
1209 Compare two query reply records.
1210 ***************************************************************************/
1211
1212 static int name_query_comp(unsigned char *p1, unsigned char *p2)
/* [<][>][^][v][top][bottom][index][help] */
1213 {
1214 return matching_len_bits(p2+2, sort_ip, 4) -
1215 matching_len_bits(p1+2, sort_ip, 4);
1216 }
1217
1218 /****************************************************************************
1219 Sort a set of 6 byte name query response records so that the IPs that
1220 have the most leading bits in common with the specified address come first.
1221 ***************************************************************************/
1222
1223 void sort_query_replies(char *data, int n, struct in_addr ip)
/* [<][>][^][v][top][bottom][index][help] */
1224 {
1225 if (n <= 1)
1226 return;
1227
1228 putip(sort_ip, (char *)&ip);
1229
1230 qsort(data, n, 6, QSORT_CAST name_query_comp);
1231 }
1232
1233 /****************************************************************************
1234 Interpret the weird netbios "name" into a unix fstring. Return the name type.
1235 ****************************************************************************/
1236
1237 static int name_interpret(char *in, fstring name)
/* [<][>][^][v][top][bottom][index][help] */
1238 {
1239 int ret;
1240 int len = (*in++) / 2;
1241 fstring out_string;
1242 char *out = out_string;
1243
1244 *out=0;
1245
1246 if (len > 30 || len<1)
1247 return(0);
1248
1249 while (len--) {
1250 if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
1251 *out = 0;
1252 return(0);
1253 }
1254 *out = ((in[0]-'A')<<4) + (in[1]-'A');
1255 in += 2;
1256 out++;
1257 }
1258 ret = out[-1];
1259 out[-1] = 0;
1260
1261 #ifdef NETBIOS_SCOPE
1262 /* Handle any scope names */
1263 while(*in) {
1264 *out++ = '.'; /* Scope names are separated by periods */
1265 len = *(unsigned char *)in++;
1266 StrnCpy(out, in, len);
1267 out += len;
1268 *out=0;
1269 in += len;
1270 }
1271 #endif
1272 pull_ascii_fstring(name, out_string);
1273
1274 return(ret);
1275 }
1276
1277 /****************************************************************************
1278 Mangle a name into netbios format.
1279 Note: <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
1280 ****************************************************************************/
1281
1282 char *name_mangle(TALLOC_CTX *mem_ctx, char *In, char name_type)
/* [<][>][^][v][top][bottom][index][help] */
1283 {
1284 int i;
1285 int len;
1286 nstring buf;
1287 char *result;
1288 char *p;
1289
1290 result = talloc_array(mem_ctx, char, 33 + strlen(global_scope()) + 2);
1291 if (result == NULL) {
1292 return NULL;
1293 }
1294 p = result;
1295
1296 /* Safely copy the input string, In, into buf[]. */
1297 if (strcmp(In,"*") == 0)
1298 put_name(buf, "*", '\0', 0x00);
1299 else {
1300 /* We use an fstring here as mb dos names can expend x3 when
1301 going to utf8. */
1302 fstring buf_unix;
1303 nstring buf_dos;
1304
1305 pull_ascii_fstring(buf_unix, In);
1306 strupper_m(buf_unix);
1307
1308 push_ascii_nstring(buf_dos, buf_unix);
1309 put_name(buf, buf_dos, ' ', name_type);
1310 }
1311
1312 /* Place the length of the first field into the output buffer. */
1313 p[0] = 32;
1314 p++;
1315
1316 /* Now convert the name to the rfc1001/1002 format. */
1317 for( i = 0; i < MAX_NETBIOSNAME_LEN; i++ ) {
1318 p[i*2] = ( (buf[i] >> 4) & 0x000F ) + 'A';
1319 p[(i*2)+1] = (buf[i] & 0x000F) + 'A';
1320 }
1321 p += 32;
1322 p[0] = '\0';
1323
1324 /* Add the scope string. */
1325 for( i = 0, len = 0; *(global_scope()) != '\0'; i++, len++ ) {
1326 switch( (global_scope())[i] ) {
1327 case '\0':
1328 p[0] = len;
1329 if( len > 0 )
1330 p[len+1] = 0;
1331 return result;
1332 case '.':
1333 p[0] = len;
1334 p += (len + 1);
1335 len = -1;
1336 break;
1337 default:
1338 p[len+1] = (global_scope())[i];
1339 break;
1340 }
1341 }
1342
1343 return result;
1344 }
1345
1346 /****************************************************************************
1347 Find a pointer to a netbios name.
1348 ****************************************************************************/
1349
1350 static char *name_ptr(char *buf,int ofs)
/* [<][>][^][v][top][bottom][index][help] */
1351 {
1352 unsigned char c = *(unsigned char *)(buf+ofs);
1353
1354 if ((c & 0xC0) == 0xC0) {
1355 uint16 l = RSVAL(buf, ofs) & 0x3FFF;
1356 DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
1357 return(buf + l);
1358 } else {
1359 return(buf+ofs);
1360 }
1361 }
1362
1363 /****************************************************************************
1364 Extract a netbios name from a buf (into a unix string) return name type.
1365 ****************************************************************************/
1366
1367 int name_extract(char *buf,int ofs, fstring name)
/* [<][>][^][v][top][bottom][index][help] */
1368 {
1369 char *p = name_ptr(buf,ofs);
1370 int d = PTR_DIFF(p,buf+ofs);
1371
1372 name[0] = '\0';
1373 if (d < -50 || d > 50)
1374 return(0);
1375 return(name_interpret(p,name));
1376 }
1377
1378 /****************************************************************************
1379 Return the total storage length of a mangled name.
1380 ****************************************************************************/
1381
1382 int name_len(char *s1)
/* [<][>][^][v][top][bottom][index][help] */
1383 {
1384 /* NOTE: this argument _must_ be unsigned */
1385 unsigned char *s = (unsigned char *)s1;
1386 int len;
1387
1388 /* If the two high bits of the byte are set, return 2. */
1389 if (0xC0 == (*s & 0xC0))
1390 return(2);
1391
1392 /* Add up the length bytes. */
1393 for (len = 1; (*s); s += (*s) + 1) {
1394 len += *s + 1;
1395 SMB_ASSERT(len < 80);
1396 }
1397
1398 return(len);
1399 }