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