source: branches/samba-3.5.x/source3/libsmb/nmblib.c

Last change on this file was 596, checked in by Herwig Bauernfeind, 14 years ago

Samba 3.5: Update trunk to 3.5.8

File size: 38.3 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
24static 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
42static const char *lookup_opcode_name( int opcode )
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
59static void debug_nmb_res_rec(struct res_rec *res, const char *hdr)
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
102void debug_nmb_packet(struct packet_struct *p)
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
152static bool handle_name_ptrs(unsigned char *ubuf,int *offset,int length,
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
175static int parse_nmb_name(char *inbuf,int ofs,int length, struct nmb_name *name)
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
267void put_name(char *dest, const char *name, int pad, unsigned int name_type)
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
290static int put_nmb_name(char *buf,int offset,struct nmb_name *name)
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
345char *nmb_namestr(const struct nmb_name *n)
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
366static bool parse_alloc_res_rec(char *inbuf,int *offset,int length,
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
406static int put_res_rec(char *buf,int offset,struct res_rec *recs,int count)
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
434static int put_compressed_name_ptr(unsigned char *buf,
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
466static bool parse_dgram(char *inbuf,int length,struct dgram_packet *dgram)
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
520static bool parse_nmb(char *inbuf,int length,struct nmb_packet *nmb)
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
587static struct packet_struct *copy_nmb_packet(struct packet_struct *packet)
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 pkt_copy->recv_fd = -1;
605 pkt_copy->send_fd = -1;
606
607 /* Ensure this copy has no resource records. */
608 nmb = &packet->packet.nmb;
609 copy_nmb = &pkt_copy->packet.nmb;
610
611 copy_nmb->answers = NULL;
612 copy_nmb->nsrecs = NULL;
613 copy_nmb->additional = NULL;
614
615 /* Now copy any resource records. */
616
617 if (nmb->answers) {
618 if((copy_nmb->answers = SMB_MALLOC_ARRAY(
619 struct res_rec,nmb->header.ancount)) == NULL)
620 goto free_and_exit;
621 memcpy((char *)copy_nmb->answers, (char *)nmb->answers,
622 nmb->header.ancount * sizeof(struct res_rec));
623 }
624 if (nmb->nsrecs) {
625 if((copy_nmb->nsrecs = SMB_MALLOC_ARRAY(
626 struct res_rec, nmb->header.nscount)) == NULL)
627 goto free_and_exit;
628 memcpy((char *)copy_nmb->nsrecs, (char *)nmb->nsrecs,
629 nmb->header.nscount * sizeof(struct res_rec));
630 }
631 if (nmb->additional) {
632 if((copy_nmb->additional = SMB_MALLOC_ARRAY(
633 struct res_rec, nmb->header.arcount)) == NULL)
634 goto free_and_exit;
635 memcpy((char *)copy_nmb->additional, (char *)nmb->additional,
636 nmb->header.arcount * sizeof(struct res_rec));
637 }
638
639 return pkt_copy;
640
641 free_and_exit:
642
643 SAFE_FREE(copy_nmb->answers);
644 SAFE_FREE(copy_nmb->nsrecs);
645 SAFE_FREE(copy_nmb->additional);
646 SAFE_FREE(pkt_copy);
647
648 DEBUG(0,("copy_nmb_packet: malloc fail in resource records.\n"));
649 return NULL;
650}
651
652/*******************************************************************
653 'Copy constructor' for a dgram packet.
654******************************************************************/
655
656static struct packet_struct *copy_dgram_packet(struct packet_struct *packet)
657{
658 struct packet_struct *pkt_copy;
659
660 if(( pkt_copy = SMB_MALLOC_P(struct packet_struct)) == NULL) {
661 DEBUG(0,("copy_dgram_packet: malloc fail.\n"));
662 return NULL;
663 }
664
665 /* Structure copy of entire thing. */
666
667 *pkt_copy = *packet;
668
669 /* Ensure this copy is not locked. */
670 pkt_copy->locked = False;
671 pkt_copy->recv_fd = -1;
672 pkt_copy->send_fd = -1;
673
674 /* There are no additional pointers in a dgram packet,
675 we are finished. */
676 return pkt_copy;
677}
678
679/*******************************************************************
680 'Copy constructor' for a generic packet.
681******************************************************************/
682
683struct packet_struct *copy_packet(struct packet_struct *packet)
684{
685 if(packet->packet_type == NMB_PACKET)
686 return copy_nmb_packet(packet);
687 else if (packet->packet_type == DGRAM_PACKET)
688 return copy_dgram_packet(packet);
689 return NULL;
690}
691
692/*******************************************************************
693 Free up any resources associated with an nmb packet.
694******************************************************************/
695
696static void free_nmb_packet(struct nmb_packet *nmb)
697{
698 SAFE_FREE(nmb->answers);
699 SAFE_FREE(nmb->nsrecs);
700 SAFE_FREE(nmb->additional);
701}
702
703/*******************************************************************
704 Free up any resources associated with a dgram packet.
705******************************************************************/
706
707static void free_dgram_packet(struct dgram_packet *nmb)
708{
709 /* We have nothing to do for a dgram packet. */
710}
711
712/*******************************************************************
713 Free up any resources associated with a packet.
714******************************************************************/
715
716void free_packet(struct packet_struct *packet)
717{
718 if (packet->locked)
719 return;
720 if (packet->packet_type == NMB_PACKET)
721 free_nmb_packet(&packet->packet.nmb);
722 else if (packet->packet_type == DGRAM_PACKET)
723 free_dgram_packet(&packet->packet.dgram);
724 ZERO_STRUCTPN(packet);
725 SAFE_FREE(packet);
726}
727
728/*******************************************************************
729 Parse a packet buffer into a packet structure.
730******************************************************************/
731
732struct packet_struct *parse_packet(char *buf,int length,
733 enum packet_type packet_type,
734 struct in_addr ip,
735 int port)
736{
737 struct packet_struct *p;
738 bool ok=False;
739
740 p = SMB_MALLOC_P(struct packet_struct);
741 if (!p)
742 return(NULL);
743
744 ZERO_STRUCTP(p); /* initialize for possible padding */
745
746 p->next = NULL;
747 p->prev = NULL;
748 p->ip = ip;
749 p->port = port;
750 p->locked = False;
751 p->timestamp = time(NULL);
752 p->packet_type = packet_type;
753
754 switch (packet_type) {
755 case NMB_PACKET:
756 ok = parse_nmb(buf,length,&p->packet.nmb);
757 break;
758
759 case DGRAM_PACKET:
760 ok = parse_dgram(buf,length,&p->packet.dgram);
761 break;
762 }
763
764 if (!ok) {
765 free_packet(p);
766 return NULL;
767 }
768
769 return p;
770}
771
772/*******************************************************************
773 Read a packet from a socket and parse it, returning a packet ready
774 to be used or put on the queue. This assumes a UDP socket.
775******************************************************************/
776
777struct packet_struct *read_packet(int fd,enum packet_type packet_type)
778{
779 struct packet_struct *packet;
780 struct sockaddr_storage sa;
781 struct sockaddr_in *si = (struct sockaddr_in *)&sa;
782 char buf[MAX_DGRAM_SIZE];
783 int length;
784
785 length = read_udp_v4_socket(fd,buf,sizeof(buf),&sa);
786 if (length < MIN_DGRAM_SIZE || sa.ss_family != AF_INET) {
787 return NULL;
788 }
789
790 packet = parse_packet(buf,
791 length,
792 packet_type,
793 si->sin_addr,
794 ntohs(si->sin_port));
795 if (!packet)
796 return NULL;
797
798 packet->recv_fd = fd;
799 packet->send_fd = -1;
800
801 DEBUG(5,("Received a packet of len %d from (%s) port %d\n",
802 length, inet_ntoa(packet->ip), packet->port ) );
803
804 return(packet);
805}
806
807/*******************************************************************
808 Send a udp packet on a already open socket.
809******************************************************************/
810
811static bool send_udp(int fd,char *buf,int len,struct in_addr ip,int port)
812{
813 bool ret = False;
814 int i;
815 struct sockaddr_in sock_out;
816
817 /* set the address and port */
818 memset((char *)&sock_out,'\0',sizeof(sock_out));
819 putip((char *)&sock_out.sin_addr,(char *)&ip);
820 sock_out.sin_port = htons( port );
821 sock_out.sin_family = AF_INET;
822
823 DEBUG( 5, ( "Sending a packet of len %d to (%s) on port %d\n",
824 len, inet_ntoa(ip), port ) );
825
826 /*
827 * Patch to fix asynch error notifications from Linux kernel.
828 */
829
830 for (i = 0; i < 5; i++) {
831 ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out,
832 sizeof(sock_out)) >= 0);
833 if (ret || errno != ECONNREFUSED)
834 break;
835 }
836
837 if (!ret)
838 DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n",
839 inet_ntoa(ip),port,strerror(errno)));
840
841 return(ret);
842}
843
844/*******************************************************************
845 Build a dgram packet ready for sending.
846 If buf == NULL this is a length calculation.
847******************************************************************/
848
849static int build_dgram(char *buf, size_t len, struct dgram_packet *dgram)
850{
851 unsigned char *ubuf = (unsigned char *)buf;
852 int offset=0;
853
854 /* put in the header */
855 if (buf) {
856 ubuf[0] = dgram->header.msg_type;
857 ubuf[1] = (((int)dgram->header.flags.node_type)<<2);
858 if (dgram->header.flags.more)
859 ubuf[1] |= 1;
860 if (dgram->header.flags.first)
861 ubuf[1] |= 2;
862 RSSVAL(ubuf,2,dgram->header.dgm_id);
863 putip(ubuf+4,(char *)&dgram->header.source_ip);
864 RSSVAL(ubuf,8,dgram->header.source_port);
865 RSSVAL(ubuf,12,dgram->header.packet_offset);
866 }
867
868 offset = 14;
869
870 if (dgram->header.msg_type == 0x10 ||
871 dgram->header.msg_type == 0x11 ||
872 dgram->header.msg_type == 0x12) {
873 offset += put_nmb_name((char *)ubuf,offset,&dgram->source_name);
874 offset += put_nmb_name((char *)ubuf,offset,&dgram->dest_name);
875 }
876
877 if (buf) {
878 memcpy(ubuf+offset,dgram->data,dgram->datasize);
879 }
880 offset += dgram->datasize;
881
882 /* automatically set the dgm_length
883 * NOTE: RFC1002 says the dgm_length does *not*
884 * include the fourteen-byte header. crh
885 */
886 dgram->header.dgm_length = (offset - 14);
887 if (buf) {
888 RSSVAL(ubuf,10,dgram->header.dgm_length);
889 }
890
891 return offset;
892}
893
894/*******************************************************************
895 Build a nmb name
896*******************************************************************/
897
898void make_nmb_name( struct nmb_name *n, const char *name, int type)
899{
900 fstring unix_name;
901 memset( (char *)n, '\0', sizeof(struct nmb_name) );
902 fstrcpy(unix_name, name);
903 strupper_m(unix_name);
904 push_ascii(n->name, unix_name, sizeof(n->name), STR_TERMINATE);
905 n->name_type = (unsigned int)type & 0xFF;
906 push_ascii(n->scope, global_scope(), 64, STR_TERMINATE);
907}
908
909/*******************************************************************
910 Compare two nmb names
911******************************************************************/
912
913bool nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2)
914{
915 return ((n1->name_type == n2->name_type) &&
916 strequal(n1->name ,n2->name ) &&
917 strequal(n1->scope,n2->scope));
918}
919
920/*******************************************************************
921 Build a nmb packet ready for sending.
922 If buf == NULL this is a length calculation.
923******************************************************************/
924
925static int build_nmb(char *buf, size_t len, struct nmb_packet *nmb)
926{
927 unsigned char *ubuf = (unsigned char *)buf;
928 int offset=0;
929
930 if (len && len < 12) {
931 return 0;
932 }
933
934 /* put in the header */
935 if (buf) {
936 RSSVAL(ubuf,offset,nmb->header.name_trn_id);
937 ubuf[offset+2] = (nmb->header.opcode & 0xF) << 3;
938 if (nmb->header.response)
939 ubuf[offset+2] |= (1<<7);
940 if (nmb->header.nm_flags.authoritative &&
941 nmb->header.response)
942 ubuf[offset+2] |= 0x4;
943 if (nmb->header.nm_flags.trunc)
944 ubuf[offset+2] |= 0x2;
945 if (nmb->header.nm_flags.recursion_desired)
946 ubuf[offset+2] |= 0x1;
947 if (nmb->header.nm_flags.recursion_available &&
948 nmb->header.response)
949 ubuf[offset+3] |= 0x80;
950 if (nmb->header.nm_flags.bcast)
951 ubuf[offset+3] |= 0x10;
952 ubuf[offset+3] |= (nmb->header.rcode & 0xF);
953
954 RSSVAL(ubuf,offset+4,nmb->header.qdcount);
955 RSSVAL(ubuf,offset+6,nmb->header.ancount);
956 RSSVAL(ubuf,offset+8,nmb->header.nscount);
957 RSSVAL(ubuf,offset+10,nmb->header.arcount);
958 }
959
960 offset += 12;
961 if (nmb->header.qdcount) {
962 /* XXXX this doesn't handle a qdcount of > 1 */
963 if (len) {
964 /* Length check. */
965 int extra = put_nmb_name(NULL,offset,
966 &nmb->question.question_name);
967 if (offset + extra > len) {
968 return 0;
969 }
970 }
971 offset += put_nmb_name((char *)ubuf,offset,
972 &nmb->question.question_name);
973 if (buf) {
974 RSSVAL(ubuf,offset,nmb->question.question_type);
975 RSSVAL(ubuf,offset+2,nmb->question.question_class);
976 }
977 offset += 4;
978 }
979
980 if (nmb->header.ancount) {
981 if (len) {
982 /* Length check. */
983 int extra = put_res_rec(NULL,offset,nmb->answers,
984 nmb->header.ancount);
985 if (offset + extra > len) {
986 return 0;
987 }
988 }
989 offset += put_res_rec((char *)ubuf,offset,nmb->answers,
990 nmb->header.ancount);
991 }
992
993 if (nmb->header.nscount) {
994 if (len) {
995 /* Length check. */
996 int extra = put_res_rec(NULL,offset,nmb->nsrecs,
997 nmb->header.nscount);
998 if (offset + extra > len) {
999 return 0;
1000 }
1001 }
1002 offset += put_res_rec((char *)ubuf,offset,nmb->nsrecs,
1003 nmb->header.nscount);
1004 }
1005
1006 /*
1007 * The spec says we must put compressed name pointers
1008 * in the following outgoing packets :
1009 * NAME_REGISTRATION_REQUEST, NAME_REFRESH_REQUEST,
1010 * NAME_RELEASE_REQUEST.
1011 */
1012
1013 if((nmb->header.response == False) &&
1014 ((nmb->header.opcode == NMB_NAME_REG_OPCODE) ||
1015 (nmb->header.opcode == NMB_NAME_RELEASE_OPCODE) ||
1016 (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_8) ||
1017 (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_9) ||
1018 (nmb->header.opcode == NMB_NAME_MULTIHOMED_REG_OPCODE)) &&
1019 (nmb->header.arcount == 1)) {
1020
1021 if (len) {
1022 /* Length check. */
1023 int extra = put_compressed_name_ptr(NULL,offset,
1024 nmb->additional,12);
1025 if (offset + extra > len) {
1026 return 0;
1027 }
1028 }
1029 offset += put_compressed_name_ptr(ubuf,offset,
1030 nmb->additional,12);
1031 } else if (nmb->header.arcount) {
1032 if (len) {
1033 /* Length check. */
1034 int extra = put_res_rec(NULL,offset,nmb->additional,
1035 nmb->header.arcount);
1036 if (offset + extra > len) {
1037 return 0;
1038 }
1039 }
1040 offset += put_res_rec((char *)ubuf,offset,nmb->additional,
1041 nmb->header.arcount);
1042 }
1043 return offset;
1044}
1045
1046/*******************************************************************
1047 Linearise a packet.
1048******************************************************************/
1049
1050int build_packet(char *buf, size_t buflen, struct packet_struct *p)
1051{
1052 int len = 0;
1053
1054 switch (p->packet_type) {
1055 case NMB_PACKET:
1056 len = build_nmb(buf,buflen,&p->packet.nmb);
1057 break;
1058
1059 case DGRAM_PACKET:
1060 len = build_dgram(buf,buflen,&p->packet.dgram);
1061 break;
1062 }
1063
1064 return len;
1065}
1066
1067/*******************************************************************
1068 Send a packet_struct.
1069******************************************************************/
1070
1071bool send_packet(struct packet_struct *p)
1072{
1073 char buf[1024];
1074 int len=0;
1075
1076 memset(buf,'\0',sizeof(buf));
1077
1078 len = build_packet(buf, sizeof(buf), p);
1079
1080 if (!len)
1081 return(False);
1082
1083 return(send_udp(p->send_fd,buf,len,p->ip,p->port));
1084}
1085
1086/****************************************************************************
1087 Receive a packet with timeout on a open UDP filedescriptor.
1088 The timeout is in milliseconds
1089***************************************************************************/
1090
1091struct packet_struct *receive_packet(int fd,enum packet_type type,int t)
1092{
1093 fd_set fds;
1094 struct timeval timeout;
1095 int ret;
1096
1097 if (fd < 0 || fd >= FD_SETSIZE) {
1098 errno = EBADF;
1099 return NULL;
1100 }
1101
1102 FD_ZERO(&fds);
1103 FD_SET(fd,&fds);
1104 timeout.tv_sec = t/1000;
1105 timeout.tv_usec = 1000*(t%1000);
1106
1107 if ((ret = sys_select_intr(fd+1,&fds,NULL,NULL,&timeout)) == -1) {
1108 /* errno should be EBADF or EINVAL. */
1109 DEBUG(0,("select returned -1, errno = %s (%d)\n",
1110 strerror(errno), errno));
1111 return NULL;
1112 }
1113
1114 if (ret == 0) /* timeout */
1115 return NULL;
1116
1117 if (FD_ISSET(fd,&fds))
1118 return(read_packet(fd,type));
1119
1120 return(NULL);
1121}
1122
1123/****************************************************************************
1124 Receive a UDP/137 packet either via UDP or from the unexpected packet
1125 queue. The packet must be a reply packet and have the specified trn_id.
1126 The timeout is in milliseconds.
1127***************************************************************************/
1128
1129struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id)
1130{
1131 struct packet_struct *p;
1132
1133 p = receive_packet(fd, NMB_PACKET, t);
1134
1135 if (p && p->packet.nmb.header.response &&
1136 p->packet.nmb.header.name_trn_id == trn_id) {
1137 return p;
1138 }
1139 if (p)
1140 free_packet(p);
1141
1142 /* try the unexpected packet queue */
1143 return receive_unexpected(NMB_PACKET, trn_id, NULL);
1144}
1145
1146/****************************************************************************
1147 Receive a UDP/138 packet either via UDP or from the unexpected packet
1148 queue. The packet must be a reply packet and have the specified mailslot name
1149 The timeout is in milliseconds.
1150***************************************************************************/
1151
1152struct packet_struct *receive_dgram_packet(int fd, int t,
1153 const char *mailslot_name)
1154{
1155 struct packet_struct *p;
1156
1157 p = receive_packet(fd, DGRAM_PACKET, t);
1158
1159 if (p && match_mailslot_name(p, mailslot_name)) {
1160 return p;
1161 }
1162 if (p)
1163 free_packet(p);
1164
1165 /* try the unexpected packet queue */
1166 return receive_unexpected(DGRAM_PACKET, 0, mailslot_name);
1167}
1168
1169/****************************************************************************
1170 See if a datagram has the right mailslot name.
1171***************************************************************************/
1172
1173bool match_mailslot_name(struct packet_struct *p, const char *mailslot_name)
1174{
1175 struct dgram_packet *dgram = &p->packet.dgram;
1176 char *buf;
1177
1178 buf = &dgram->data[0];
1179 buf -= 4;
1180
1181 buf = smb_buf(buf);
1182
1183 if (memcmp(buf, mailslot_name, strlen(mailslot_name)+1) == 0) {
1184 return True;
1185 }
1186
1187 return False;
1188}
1189
1190/****************************************************************************
1191 Return the number of bits that match between two len character buffers
1192***************************************************************************/
1193
1194int matching_len_bits(unsigned char *p1, unsigned char *p2, size_t len)
1195{
1196 size_t i, j;
1197 int ret = 0;
1198 for (i=0; i<len; i++) {
1199 if (p1[i] != p2[i])
1200 break;
1201 ret += 8;
1202 }
1203
1204 if (i==len)
1205 return ret;
1206
1207 for (j=0; j<8; j++) {
1208 if ((p1[i] & (1<<(7-j))) != (p2[i] & (1<<(7-j))))
1209 break;
1210 ret++;
1211 }
1212
1213 return ret;
1214}
1215
1216static unsigned char sort_ip[4];
1217
1218/****************************************************************************
1219 Compare two query reply records.
1220***************************************************************************/
1221
1222static int name_query_comp(unsigned char *p1, unsigned char *p2)
1223{
1224 return matching_len_bits(p2+2, sort_ip, 4) -
1225 matching_len_bits(p1+2, sort_ip, 4);
1226}
1227
1228/****************************************************************************
1229 Sort a set of 6 byte name query response records so that the IPs that
1230 have the most leading bits in common with the specified address come first.
1231***************************************************************************/
1232
1233void sort_query_replies(char *data, int n, struct in_addr ip)
1234{
1235 if (n <= 1)
1236 return;
1237
1238 putip(sort_ip, (char *)&ip);
1239
1240 qsort(data, n, 6, QSORT_CAST name_query_comp);
1241}
1242
1243/****************************************************************************
1244 Interpret the weird netbios "name" into a unix fstring. Return the name type.
1245 Returns -1 on error.
1246****************************************************************************/
1247
1248static int name_interpret(unsigned char *buf, size_t buf_len,
1249 unsigned char *in, fstring name)
1250{
1251 unsigned char *end_ptr = buf + buf_len;
1252 int ret;
1253 unsigned int len;
1254 fstring out_string;
1255 unsigned char *out = (unsigned char *)out_string;
1256
1257 *out=0;
1258
1259 if (in >= end_ptr) {
1260 return -1;
1261 }
1262 len = (*in++) / 2;
1263
1264 if (len<1) {
1265 return -1;
1266 }
1267
1268 while (len--) {
1269 if (&in[1] >= end_ptr) {
1270 return -1;
1271 }
1272 if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
1273 *out = 0;
1274 return(0);
1275 }
1276 *out = ((in[0]-'A')<<4) + (in[1]-'A');
1277 in += 2;
1278 out++;
1279 if (PTR_DIFF(out,out_string) >= sizeof(fstring)) {
1280 return -1;
1281 }
1282 }
1283 ret = out[-1];
1284 out[-1] = 0;
1285
1286 pull_ascii_fstring(name, out_string);
1287
1288 return(ret);
1289}
1290
1291/****************************************************************************
1292 Mangle a name into netbios format.
1293 Note: <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
1294****************************************************************************/
1295
1296char *name_mangle(TALLOC_CTX *mem_ctx, const char *In, char name_type)
1297{
1298 int i;
1299 int len;
1300 nstring buf;
1301 char *result;
1302 char *p;
1303
1304 result = talloc_array(mem_ctx, char, 33 + strlen(global_scope()) + 2);
1305 if (result == NULL) {
1306 return NULL;
1307 }
1308 p = result;
1309
1310 /* Safely copy the input string, In, into buf[]. */
1311 if (strcmp(In,"*") == 0)
1312 put_name(buf, "*", '\0', 0x00);
1313 else {
1314 /* We use an fstring here as mb dos names can expend x3 when
1315 going to utf8. */
1316 fstring buf_unix;
1317 nstring buf_dos;
1318
1319 pull_ascii_fstring(buf_unix, In);
1320 strupper_m(buf_unix);
1321
1322 push_ascii_nstring(buf_dos, buf_unix);
1323 put_name(buf, buf_dos, ' ', name_type);
1324 }
1325
1326 /* Place the length of the first field into the output buffer. */
1327 p[0] = 32;
1328 p++;
1329
1330 /* Now convert the name to the rfc1001/1002 format. */
1331 for( i = 0; i < MAX_NETBIOSNAME_LEN; i++ ) {
1332 p[i*2] = ( (buf[i] >> 4) & 0x000F ) + 'A';
1333 p[(i*2)+1] = (buf[i] & 0x000F) + 'A';
1334 }
1335 p += 32;
1336 p[0] = '\0';
1337
1338 /* Add the scope string. */
1339 for( i = 0, len = 0; *(global_scope()) != '\0'; i++, len++ ) {
1340 switch( (global_scope())[i] ) {
1341 case '\0':
1342 p[0] = len;
1343 if( len > 0 )
1344 p[len+1] = 0;
1345 return result;
1346 case '.':
1347 p[0] = len;
1348 p += (len + 1);
1349 len = -1;
1350 break;
1351 default:
1352 p[len+1] = (global_scope())[i];
1353 break;
1354 }
1355 }
1356
1357 return result;
1358}
1359
1360/****************************************************************************
1361 Find a pointer to a netbios name.
1362****************************************************************************/
1363
1364static unsigned char *name_ptr(unsigned char *buf, size_t buf_len, unsigned int ofs)
1365{
1366 unsigned char c = 0;
1367
1368 if (ofs > buf_len || buf_len < 1) {
1369 return NULL;
1370 }
1371
1372 c = *(unsigned char *)(buf+ofs);
1373 if ((c & 0xC0) == 0xC0) {
1374 uint16 l = 0;
1375
1376 if (ofs > buf_len - 1) {
1377 return NULL;
1378 }
1379 l = RSVAL(buf, ofs) & 0x3FFF;
1380 if (l > buf_len) {
1381 return NULL;
1382 }
1383 DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
1384 return(buf + l);
1385 } else {
1386 return(buf+ofs);
1387 }
1388}
1389
1390/****************************************************************************
1391 Extract a netbios name from a buf (into a unix string) return name type.
1392 Returns -1 on error.
1393****************************************************************************/
1394
1395int name_extract(unsigned char *buf, size_t buf_len, unsigned int ofs, fstring name)
1396{
1397 unsigned char *p = name_ptr(buf,buf_len,ofs);
1398
1399 name[0] = '\0';
1400 if (p == NULL) {
1401 return -1;
1402 }
1403 return(name_interpret(buf,buf_len,p,name));
1404}
1405
1406/****************************************************************************
1407 Return the total storage length of a mangled name.
1408 Returns -1 on error.
1409****************************************************************************/
1410
1411int name_len(unsigned char *s1, size_t buf_len)
1412{
1413 /* NOTE: this argument _must_ be unsigned */
1414 unsigned char *s = (unsigned char *)s1;
1415 int len = 0;
1416
1417 if (buf_len < 1) {
1418 return -1;
1419 }
1420 /* If the two high bits of the byte are set, return 2. */
1421 if (0xC0 == (*s & 0xC0)) {
1422 if (buf_len < 2) {
1423 return -1;
1424 }
1425 return(2);
1426 }
1427
1428 /* Add up the length bytes. */
1429 for (len = 1; (*s); s += (*s) + 1) {
1430 len += *s + 1;
1431 if (len > buf_len) {
1432 return -1;
1433 }
1434 }
1435
1436 return(len);
1437}
Note: See TracBrowser for help on using the repository browser.