source: trunk-3.0/source/libsmb/nmblib.c@ 101

Last change on this file since 101 was 1, checked in by Paul Smedley, 18 years ago

Initial code import

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