source: vendor/current/source3/libsmb/nmblib.c

Last change on this file was 988, checked in by Silvan Scherrer, 9 years ago

Samba Server: update vendor to version 4.4.3

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