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

Last change on this file was 740, checked in by Silvan Scherrer, 13 years ago

Samba Server: update vendor to 3.6.0

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