libsmb: Expose protocol-agnostic cli_writeall_send/recv
[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) {
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         size_t m,n=0;
180         unsigned char *ubuf = (unsigned char *)inbuf;
181         int ret = 0;
182         bool got_pointer=False;
183         size_t 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         size_t 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 static struct packet_struct *copy_packet_talloc(
807         TALLOC_CTX *mem_ctx, const struct packet_struct *src)
808 {
809         struct packet_struct *pkt;
810
811         pkt = talloc_memdup(mem_ctx, src, sizeof(struct packet_struct));
812         if (pkt == NULL) {
813                 return NULL;
814         }
815         pkt->locked = false;
816         pkt->recv_fd = -1;
817         pkt->send_fd = -1;
818
819         if (src->packet_type == NMB_PACKET) {
820                 const struct nmb_packet *nsrc = &src->packet.nmb;
821                 struct nmb_packet *ndst = &pkt->packet.nmb;
822
823                 if (nsrc->answers != NULL) {
824                         ndst->answers = talloc_memdup(
825                                 pkt, nsrc->answers,
826                                 sizeof(struct res_rec) * nsrc->header.ancount);
827                         if (ndst->answers == NULL) {
828                                 goto fail;
829                         }
830                 }
831                 if (nsrc->nsrecs != NULL) {
832                         ndst->nsrecs = talloc_memdup(
833                                 pkt, nsrc->nsrecs,
834                                 sizeof(struct res_rec) * nsrc->header.nscount);
835                         if (ndst->nsrecs == NULL) {
836                                 goto fail;
837                         }
838                 }
839                 if (nsrc->additional != NULL) {
840                         ndst->additional = talloc_memdup(
841                                 pkt, nsrc->additional,
842                                 sizeof(struct res_rec) * nsrc->header.arcount);
843                         if (ndst->additional == NULL) {
844                                 goto fail;
845                         }
846                 }
847         }
848
849         return pkt;
850
851         /*
852          * DGRAM packets have no substructures
853          */
854
855 fail:
856         TALLOC_FREE(pkt);
857         return NULL;
858 }
859
860 struct packet_struct *parse_packet_talloc(TALLOC_CTX *mem_ctx,
861                                           char *buf,int length,
862                                           enum packet_type packet_type,
863                                           struct in_addr ip,
864                                           int port)
865 {
866         struct packet_struct *pkt, *result;
867
868         pkt = parse_packet(buf, length, packet_type, ip, port);
869         if (pkt == NULL) {
870                 return NULL;
871         }
872         result = copy_packet_talloc(mem_ctx, pkt);
873         free_packet(pkt);
874         return result;
875 }
876
877 /*******************************************************************
878  Send a udp packet on a already open socket.
879 ******************************************************************/
880
881 static bool send_udp(int fd,char *buf,int len,struct in_addr ip,int port)
882 {
883         bool ret = False;
884         int i;
885         struct sockaddr_in sock_out;
886
887         /* set the address and port */
888         memset((char *)&sock_out,'\0',sizeof(sock_out));
889         putip((char *)&sock_out.sin_addr,(char *)&ip);
890         sock_out.sin_port = htons( port );
891         sock_out.sin_family = AF_INET;
892
893         DEBUG( 5, ( "Sending a packet of len %d to (%s) on port %d\n",
894                         len, inet_ntoa(ip), port ) );
895
896         /*
897          * Patch to fix asynch error notifications from Linux kernel.
898          */
899
900         for (i = 0; i < 5; i++) {
901                 ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out,
902                                         sizeof(sock_out)) >= 0);
903                 if (ret || errno != ECONNREFUSED)
904                         break;
905         }
906
907         if (!ret)
908                 DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n",
909                         inet_ntoa(ip),port,strerror(errno)));
910
911         return(ret);
912 }
913
914 /*******************************************************************
915  Build a dgram packet ready for sending.
916  If buf == NULL this is a length calculation.
917 ******************************************************************/
918
919 static int build_dgram(char *buf, size_t len, struct dgram_packet *dgram)
920 {
921         unsigned char *ubuf = (unsigned char *)buf;
922         int offset=0;
923
924         /* put in the header */
925         if (buf) {
926                 ubuf[0] = dgram->header.msg_type;
927                 ubuf[1] = (((int)dgram->header.flags.node_type)<<2);
928                 if (dgram->header.flags.more)
929                         ubuf[1] |= 1;
930                 if (dgram->header.flags.first)
931                         ubuf[1] |= 2;
932                 RSSVAL(ubuf,2,dgram->header.dgm_id);
933                 putip(ubuf+4,(char *)&dgram->header.source_ip);
934                 RSSVAL(ubuf,8,dgram->header.source_port);
935                 RSSVAL(ubuf,12,dgram->header.packet_offset);
936         }
937
938         offset = 14;
939
940         if (dgram->header.msg_type == 0x10 ||
941                         dgram->header.msg_type == 0x11 ||
942                         dgram->header.msg_type == 0x12) {
943                 offset += put_nmb_name((char *)ubuf,len,offset,&dgram->source_name);
944                 offset += put_nmb_name((char *)ubuf,len,offset,&dgram->dest_name);
945         }
946
947         if (buf) {
948                 memcpy(ubuf+offset,dgram->data,dgram->datasize);
949         }
950         offset += dgram->datasize;
951
952         /* automatically set the dgm_length
953          * NOTE: RFC1002 says the dgm_length does *not*
954          *       include the fourteen-byte header. crh
955          */
956         dgram->header.dgm_length = (offset - 14);
957         if (buf) {
958                 RSSVAL(ubuf,10,dgram->header.dgm_length);
959         }
960
961         return offset;
962 }
963
964 /*******************************************************************
965  Build a nmb name
966 *******************************************************************/
967
968 void make_nmb_name( struct nmb_name *n, const char *name, int type)
969 {
970         fstring unix_name;
971         memset( (char *)n, '\0', sizeof(struct nmb_name) );
972         fstrcpy(unix_name, name);
973         (void)strupper_m(unix_name);
974         push_ascii(n->name, unix_name, sizeof(n->name), STR_TERMINATE);
975         n->name_type = (unsigned int)type & 0xFF;
976         push_ascii(n->scope,  lp_netbios_scope(), 64, STR_TERMINATE);
977 }
978
979 /*******************************************************************
980   Compare two nmb names
981 ******************************************************************/
982
983 bool nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2)
984 {
985         return ((n1->name_type == n2->name_type) &&
986                 strequal(n1->name ,n2->name ) &&
987                 strequal(n1->scope,n2->scope));
988 }
989
990 /*******************************************************************
991  Build a nmb packet ready for sending.
992  If buf == NULL this is a length calculation.
993 ******************************************************************/
994
995 static int build_nmb(char *buf, size_t len, struct nmb_packet *nmb)
996 {
997         unsigned char *ubuf = (unsigned char *)buf;
998         int offset=0;
999
1000         if (len && len < 12) {
1001                 return 0;
1002         }
1003
1004         /* put in the header */
1005         if (buf) {
1006                 RSSVAL(ubuf,offset,nmb->header.name_trn_id);
1007                 ubuf[offset+2] = (nmb->header.opcode & 0xF) << 3;
1008                 if (nmb->header.response)
1009                         ubuf[offset+2] |= (1<<7);
1010                 if (nmb->header.nm_flags.authoritative &&
1011                                 nmb->header.response)
1012                         ubuf[offset+2] |= 0x4;
1013                 if (nmb->header.nm_flags.trunc)
1014                         ubuf[offset+2] |= 0x2;
1015                 if (nmb->header.nm_flags.recursion_desired)
1016                         ubuf[offset+2] |= 0x1;
1017                 if (nmb->header.nm_flags.recursion_available &&
1018                                 nmb->header.response)
1019                         ubuf[offset+3] |= 0x80;
1020                 if (nmb->header.nm_flags.bcast)
1021                         ubuf[offset+3] |= 0x10;
1022                 ubuf[offset+3] |= (nmb->header.rcode & 0xF);
1023
1024                 RSSVAL(ubuf,offset+4,nmb->header.qdcount);
1025                 RSSVAL(ubuf,offset+6,nmb->header.ancount);
1026                 RSSVAL(ubuf,offset+8,nmb->header.nscount);
1027                 RSSVAL(ubuf,offset+10,nmb->header.arcount);
1028         }
1029
1030         offset += 12;
1031         if (nmb->header.qdcount) {
1032                 /* XXXX this doesn't handle a qdcount of > 1 */
1033                 if (len) {
1034                         /* Length check. */
1035                         int extra = put_nmb_name(NULL,0,offset,
1036                                         &nmb->question.question_name);
1037                         if (offset + extra > len) {
1038                                 return 0;
1039                         }
1040                 }
1041                 offset += put_nmb_name((char *)ubuf,len,offset,
1042                                 &nmb->question.question_name);
1043                 if (buf) {
1044                         RSSVAL(ubuf,offset,nmb->question.question_type);
1045                         RSSVAL(ubuf,offset+2,nmb->question.question_class);
1046                 }
1047                 offset += 4;
1048         }
1049
1050         if (nmb->header.ancount) {
1051                 if (len) {
1052                         /* Length check. */
1053                         int extra = put_res_rec(NULL,0,offset,nmb->answers,
1054                                         nmb->header.ancount);
1055                         if (offset + extra > len) {
1056                                 return 0;
1057                         }
1058                 }
1059                 offset += put_res_rec((char *)ubuf,len,offset,nmb->answers,
1060                                 nmb->header.ancount);
1061         }
1062
1063         if (nmb->header.nscount) {
1064                 if (len) {
1065                         /* Length check. */
1066                         int extra = put_res_rec(NULL,0,offset,nmb->nsrecs,
1067                                 nmb->header.nscount);
1068                         if (offset + extra > len) {
1069                                 return 0;
1070                         }
1071                 }
1072                 offset += put_res_rec((char *)ubuf,len,offset,nmb->nsrecs,
1073                                 nmb->header.nscount);
1074         }
1075
1076         /*
1077          * The spec says we must put compressed name pointers
1078          * in the following outgoing packets :
1079          * NAME_REGISTRATION_REQUEST, NAME_REFRESH_REQUEST,
1080          * NAME_RELEASE_REQUEST.
1081          */
1082
1083         if((nmb->header.response == False) &&
1084                 ((nmb->header.opcode == NMB_NAME_REG_OPCODE) ||
1085                 (nmb->header.opcode == NMB_NAME_RELEASE_OPCODE) ||
1086                 (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_8) ||
1087                 (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_9) ||
1088                 (nmb->header.opcode == NMB_NAME_MULTIHOMED_REG_OPCODE)) &&
1089                 (nmb->header.arcount == 1)) {
1090
1091                 if (len) {
1092                         /* Length check. */
1093                         int extra = put_compressed_name_ptr(NULL,offset,
1094                                         nmb->additional,12);
1095                         if (offset + extra > len) {
1096                                 return 0;
1097                         }
1098                 }
1099                 offset += put_compressed_name_ptr(ubuf,offset,
1100                                 nmb->additional,12);
1101         } else if (nmb->header.arcount) {
1102                 if (len) {
1103                         /* Length check. */
1104                         int extra = put_res_rec(NULL,0,offset,nmb->additional,
1105                                 nmb->header.arcount);
1106                         if (offset + extra > len) {
1107                                 return 0;
1108                         }
1109                 }
1110                 offset += put_res_rec((char *)ubuf,len,offset,nmb->additional,
1111                         nmb->header.arcount);
1112         }
1113         return offset;
1114 }
1115
1116 /*******************************************************************
1117  Linearise a packet.
1118 ******************************************************************/
1119
1120 int build_packet(char *buf, size_t buflen, struct packet_struct *p)
1121 {
1122         int len = 0;
1123
1124         switch (p->packet_type) {
1125         case NMB_PACKET:
1126                 len = build_nmb(buf,buflen,&p->packet.nmb);
1127                 break;
1128
1129         case DGRAM_PACKET:
1130                 len = build_dgram(buf,buflen,&p->packet.dgram);
1131                 break;
1132         }
1133
1134         return len;
1135 }
1136
1137 /*******************************************************************
1138  Send a packet_struct.
1139 ******************************************************************/
1140
1141 bool send_packet(struct packet_struct *p)
1142 {
1143         char buf[1024];
1144         int len=0;
1145
1146         memset(buf,'\0',sizeof(buf));
1147
1148         len = build_packet(buf, sizeof(buf), p);
1149
1150         if (!len)
1151                 return(False);
1152
1153         return(send_udp(p->send_fd,buf,len,p->ip,p->port));
1154 }
1155
1156 /****************************************************************************
1157  Receive a UDP/138 packet either via UDP or from the unexpected packet
1158  queue. The packet must be a reply packet and have the specified mailslot name
1159  The timeout is in milliseconds.
1160 ***************************************************************************/
1161
1162 /****************************************************************************
1163  See if a datagram has the right mailslot name.
1164 ***************************************************************************/
1165
1166 bool match_mailslot_name(struct packet_struct *p, const char *mailslot_name)
1167 {
1168         struct dgram_packet *dgram = &p->packet.dgram;
1169         char *buf;
1170
1171         buf = &dgram->data[0];
1172         buf -= 4;
1173
1174         buf = smb_buf(buf);
1175
1176         if (memcmp(buf, mailslot_name, strlen(mailslot_name)+1) == 0) {
1177                 return True;
1178         }
1179
1180         return False;
1181 }
1182
1183 /****************************************************************************
1184  Return the number of bits that match between two len character buffers
1185 ***************************************************************************/
1186
1187 int matching_len_bits(const unsigned char *p1, const unsigned char *p2, size_t len)
1188 {
1189         size_t i, j;
1190         int ret = 0;
1191         for (i=0; i<len; i++) {
1192                 if (p1[i] != p2[i])
1193                         break;
1194                 ret += 8;
1195         }
1196
1197         if (i==len)
1198                 return ret;
1199
1200         for (j=0; j<8; j++) {
1201                 if ((p1[i] & (1<<(7-j))) != (p2[i] & (1<<(7-j))))
1202                         break;
1203                 ret++;
1204         }
1205
1206         return ret;
1207 }
1208
1209 static unsigned char sort_ip[4];
1210
1211 /****************************************************************************
1212  Compare two query reply records.
1213 ***************************************************************************/
1214
1215 static int name_query_comp(unsigned char *p1, unsigned char *p2)
1216 {
1217         return matching_len_bits(p2+2, sort_ip, 4) -
1218                 matching_len_bits(p1+2, sort_ip, 4);
1219 }
1220
1221 /****************************************************************************
1222  Sort a set of 6 byte name query response records so that the IPs that
1223  have the most leading bits in common with the specified address come first.
1224 ***************************************************************************/
1225
1226 void sort_query_replies(char *data, int n, struct in_addr ip)
1227 {
1228         if (n <= 1)
1229                 return;
1230
1231         putip(sort_ip, (char *)&ip);
1232
1233         /* TODO:
1234            this can't use TYPESAFE_QSORT() as the types are wrong.
1235            It should be fixed to use a real type instead of char*
1236         */
1237         qsort(data, n, 6, QSORT_CAST name_query_comp);
1238 }
1239
1240 /****************************************************************************
1241  Interpret the weird netbios "name" into a unix fstring. Return the name type.
1242  Returns -1 on error.
1243 ****************************************************************************/
1244
1245 static int name_interpret(unsigned char *buf, size_t buf_len,
1246                 unsigned char *in, fstring name)
1247 {
1248         unsigned char *end_ptr = buf + buf_len;
1249         int ret;
1250         unsigned int len;
1251         fstring out_string;
1252         unsigned char *out = (unsigned char *)out_string;
1253
1254         *out=0;
1255
1256         if (in >= end_ptr) {
1257                 return -1;
1258         }
1259         len = (*in++) / 2;
1260
1261         if (len<1) {
1262                 return -1;
1263         }
1264
1265         while (len--) {
1266                 if (&in[1] >= end_ptr) {
1267                         return -1;
1268                 }
1269                 if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
1270                         *out = 0;
1271                         return(0);
1272                 }
1273                 *out = ((in[0]-'A')<<4) + (in[1]-'A');
1274                 in += 2;
1275                 out++;
1276                 if (PTR_DIFF(out,out_string) >= sizeof(fstring)) {
1277                         return -1;
1278                 }
1279         }
1280         ret = out[-1];
1281         out[-1] = 0;
1282
1283         pull_ascii_fstring(name, out_string);
1284
1285         return(ret);
1286 }
1287
1288 /****************************************************************************
1289  Mangle a name into netbios format.
1290  Note:  <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
1291 ****************************************************************************/
1292
1293 char *name_mangle(TALLOC_CTX *mem_ctx, const char *In, char name_type)
1294 {
1295         int   i;
1296         int   len;
1297         nstring buf;
1298         char *result;
1299         char *p;
1300
1301         result = talloc_array(mem_ctx, char, 33 + strlen(lp_netbios_scope()) + 2);
1302         if (result == NULL) {
1303                 return NULL;
1304         }
1305         p = result;
1306
1307         /* Safely copy the input string, In, into buf[]. */
1308         if (strcmp(In,"*") == 0)
1309                 put_name(buf, "*", '\0', 0x00);
1310         else {
1311                 /* We use an fstring here as mb dos names can expend x3 when
1312                    going to utf8. */
1313                 fstring buf_unix;
1314                 nstring buf_dos;
1315
1316                 pull_ascii_fstring(buf_unix, In);
1317                 if (!strupper_m(buf_unix)) {
1318                         return NULL;
1319                 }
1320
1321                 push_ascii_nstring(buf_dos, buf_unix);
1322                 put_name(buf, buf_dos, ' ', name_type);
1323         }
1324
1325         /* Place the length of the first field into the output buffer. */
1326         p[0] = 32;
1327         p++;
1328
1329         /* Now convert the name to the rfc1001/1002 format. */
1330         for( i = 0; i < MAX_NETBIOSNAME_LEN; i++ ) {
1331                 p[i*2]     = ( (buf[i] >> 4) & 0x000F ) + 'A';
1332                 p[(i*2)+1] = (buf[i] & 0x000F) + 'A';
1333         }
1334         p += 32;
1335         p[0] = '\0';
1336
1337         /* Add the scope string. */
1338         for( i = 0, len = 0; *(lp_netbios_scope()) != '\0'; i++, len++ ) {
1339                 switch( (lp_netbios_scope())[i] ) {
1340                         case '\0':
1341                                 p[0] = len;
1342                                 if( len > 0 )
1343                                         p[len+1] = 0;
1344                                 return result;
1345                         case '.':
1346                                 p[0] = len;
1347                                 p   += (len + 1);
1348                                 len  = -1;
1349                                 break;
1350                         default:
1351                                 p[len+1] = (lp_netbios_scope())[i];
1352                                 break;
1353                 }
1354         }
1355
1356         return result;
1357 }
1358
1359 /****************************************************************************
1360  Find a pointer to a netbios name.
1361 ****************************************************************************/
1362
1363 static unsigned char *name_ptr(unsigned char *buf, size_t buf_len, unsigned int ofs)
1364 {
1365         unsigned char c = 0;
1366
1367         if (ofs > buf_len || buf_len < 1) {
1368                 return NULL;
1369         }
1370
1371         c = *(unsigned char *)(buf+ofs);
1372         if ((c & 0xC0) == 0xC0) {
1373                 uint16_t l = 0;
1374
1375                 if (ofs > buf_len - 1) {
1376                         return NULL;
1377                 }
1378                 l = RSVAL(buf, ofs) & 0x3FFF;
1379                 if (l > buf_len) {
1380                         return NULL;
1381                 }
1382                 DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
1383                 return(buf + l);
1384         } else {
1385                 return(buf+ofs);
1386         }
1387 }
1388
1389 /****************************************************************************
1390  Extract a netbios name from a buf (into a unix string) return name type.
1391  Returns -1 on error.
1392 ****************************************************************************/
1393
1394 int name_extract(unsigned char *buf, size_t buf_len, unsigned int ofs, fstring name)
1395 {
1396         unsigned char *p = name_ptr(buf,buf_len,ofs);
1397
1398         name[0] = '\0';
1399         if (p == NULL) {
1400                 return -1;
1401         }
1402         return(name_interpret(buf,buf_len,p,name));
1403 }
1404
1405 /****************************************************************************
1406  Return the total storage length of a mangled name.
1407  Returns -1 on error.
1408 ****************************************************************************/
1409
1410 int name_len(unsigned char *s1, size_t buf_len)
1411 {
1412         /* NOTE: this argument _must_ be unsigned */
1413         unsigned char *s = (unsigned char *)s1;
1414         int len = 0;
1415
1416         if (buf_len < 1) {
1417                 return -1;
1418         }
1419         /* If the two high bits of the byte are set, return 2. */
1420         if (0xC0 == (*s & 0xC0)) {
1421                 if (buf_len < 2) {
1422                         return -1;
1423                 }
1424                 return(2);
1425         }
1426
1427         /* Add up the length bytes. */
1428         for (len = 1; (*s); s += (*s) + 1) {
1429                 len += *s + 1;
1430                 if (len > buf_len) {
1431                         return -1;
1432                 }
1433         }
1434
1435         return(len);
1436 }