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