fixed a comment
[bbaumbach/samba-autobuild/.git] / source3 / libsmb / nmblib.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    NBT netbios library routines
5    Copyright (C) Andrew Tridgell 1994-1998
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 2 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, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20    
21 */
22
23 #include "includes.h"
24
25 extern int DEBUGLEVEL;
26
27 int num_good_sends = 0;
28 int num_good_receives = 0;
29
30 static struct opcode_names {
31         char *nmb_opcode_name;
32         int opcode;
33 } nmb_header_opcode_names[] = {
34       {"Query",           0 },
35       {"Registration",      5 },
36       {"Release",           6 },
37       {"WACK",              7 },
38       {"Refresh",           8 },
39       {"Refresh(altcode)",  9 },
40       {"Multi-homed Registration", 15 },
41       {0, -1 }
42 };
43
44 /****************************************************************************
45  * Lookup a nmb opcode name.
46  ****************************************************************************/
47 static char *lookup_opcode_name( int opcode )
48 {
49   struct opcode_names *op_namep;
50   int i;
51
52   for(i = 0; nmb_header_opcode_names[i].nmb_opcode_name != 0; i++) {
53     op_namep = &nmb_header_opcode_names[i];
54     if(opcode == op_namep->opcode)
55       return op_namep->nmb_opcode_name;
56   }
57   return "<unknown opcode>";
58 }
59
60 /****************************************************************************
61   print out a res_rec structure
62   ****************************************************************************/
63 static void debug_nmb_res_rec(struct res_rec *res, char *hdr)
64 {
65   int i, j;
66
67   DEBUGADD( 4, ( "    %s: nmb_name=%s rr_type=%d rr_class=%d ttl=%d\n",
68                  hdr,
69                  nmb_namestr(&res->rr_name),
70                  res->rr_type,
71                  res->rr_class,
72                  res->ttl ) );
73
74   if( res->rdlength == 0 || res->rdata == NULL )
75     return;
76
77   for (i = 0; i < res->rdlength; i+= 16)
78     {
79       DEBUGADD(4, ("    %s %3x char ", hdr, i));
80
81       for (j = 0; j < 16; j++)
82         {
83           unsigned char x = res->rdata[i+j];
84           if (x < 32 || x > 127) x = '.';
85           
86           if (i+j >= res->rdlength) break;
87           DEBUGADD(4, ("%c", x));
88         }
89       
90       DEBUGADD(4, ("   hex "));
91
92       for (j = 0; j < 16; j++)
93         {
94           if (i+j >= res->rdlength) break;
95           DEBUGADD(4, ("%02X", (unsigned char)res->rdata[i+j]));
96         }
97       
98       DEBUGADD(4, ("\n"));
99     }
100 }
101
102 /****************************************************************************
103   process a nmb packet
104   ****************************************************************************/
105 void debug_nmb_packet(struct packet_struct *p)
106 {
107   struct nmb_packet *nmb = &p->packet.nmb;
108
109   if( DEBUGLVL( 4 ) )
110     {
111     dbgtext( "nmb packet from %s(%d) header: id=%d opcode=%s(%d) response=%s\n",
112              inet_ntoa(p->ip), p->port,
113              nmb->header.name_trn_id,
114              lookup_opcode_name(nmb->header.opcode),
115              nmb->header.opcode,
116              BOOLSTR(nmb->header.response) );
117     dbgtext( "    header: flags: bcast=%s rec_avail=%s 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 nscount=%d arcount=%d\n",
124              nmb->header.rcode,
125              nmb->header.qdcount,
126              nmb->header.ancount,
127              nmb->header.nscount,
128              nmb->header.arcount );
129     }
130
131   if (nmb->header.qdcount)
132     {
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     {
141       debug_nmb_res_rec(nmb->answers,"answers");
142     }
143   if (nmb->nsrecs && nmb->header.nscount)
144     {
145       debug_nmb_res_rec(nmb->nsrecs,"nsrecs");
146     }
147   if (nmb->additional && nmb->header.arcount)
148     {
149       debug_nmb_res_rec(nmb->additional,"additional");
150     }
151 }
152
153 /*******************************************************************
154   handle "compressed" name pointers
155   ******************************************************************/
156 static BOOL handle_name_ptrs(unsigned char *ubuf,int *offset,int length,
157                              BOOL *got_pointer,int *ret)
158 {
159   int loop_count=0;
160   
161   while ((ubuf[*offset] & 0xC0) == 0xC0) {
162     if (!*got_pointer) (*ret) += 2;
163     (*got_pointer)=True;
164     (*offset) = ((ubuf[*offset] & ~0xC0)<<8) | ubuf[(*offset)+1];
165     if (loop_count++ == 10 || (*offset) < 0 || (*offset)>(length-2)) {
166       return(False);
167     }
168   }
169   return(True);
170 }
171
172 /*******************************************************************
173   parse a nmb name from "compressed" format to something readable
174   return the space taken by the name, or 0 if the name is invalid
175   ******************************************************************/
176 static int parse_nmb_name(char *inbuf,int offset,int length, struct nmb_name *name)
177 {
178   int m,n=0;
179   unsigned char *ubuf = (unsigned char *)inbuf;
180   int ret = 0;
181   BOOL got_pointer=False;
182   int loop_count=0;
183
184   if (length - offset < 2)
185     return(0);  
186
187   /* handle initial name pointers */
188   if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret))
189     return(0);
190   
191   m = ubuf[offset];
192
193   if (!m)
194     return(0);
195   if ((m & 0xC0) || offset+m+2 > length)
196     return(0);
197
198   memset((char *)name,'\0',sizeof(*name));
199
200   /* the "compressed" part */
201   if (!got_pointer)
202     ret += m + 2;
203   offset++;
204   while (m > 0) {
205     unsigned char c1,c2;
206     c1 = ubuf[offset++]-'A';
207     c2 = ubuf[offset++]-'A';
208     if ((c1 & 0xF0) || (c2 & 0xF0) || (n > sizeof(name->name)-1))
209       return(0);
210     name->name[n++] = (c1<<4) | c2;
211     m -= 2;
212   }
213   name->name[n] = 0;
214
215   if (n==16) {
216     /* parse out the name type, 
217        its always in the 16th byte of the name */
218     name->name_type = ((unsigned char)name->name[15]) & 0xff;
219   
220     /* remove trailing spaces */
221     name->name[15] = 0;
222     n = 14;
223     while (n && name->name[n]==' ')
224       name->name[n--] = 0;  
225   }
226
227   /* now the domain parts (if any) */
228   n = 0;
229   while (ubuf[offset]) {
230     /* we can have pointers within the domain part as well */
231     if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret))
232       return(0);
233
234     m = ubuf[offset];
235     /*
236      * Don't allow null domain parts.
237      */
238     if (!m)
239       return(0);
240     if (!got_pointer)
241       ret += m+1;
242     if (n)
243       name->scope[n++] = '.';
244     if (m+2+offset>length || n+m+1>sizeof(name->scope))
245       return(0);
246     offset++;
247     while (m--)
248       name->scope[n++] = (char)ubuf[offset++];
249
250     /*
251      * Watch for malicious loops.
252      */
253     if (loop_count++ == 10)
254       return 0;
255   }
256   name->scope[n++] = 0;  
257
258   return(ret);
259 }
260
261
262 /*******************************************************************
263   put a compressed nmb name into a buffer. return the length of the
264   compressed name
265
266   compressed names are really weird. The "compression" doubles the
267   size. The idea is that it also means that compressed names conform
268   to the doman name system. See RFC1002.
269   ******************************************************************/
270 static int put_nmb_name(char *buf,int offset,struct nmb_name *name)
271 {
272   int ret,m;
273   fstring buf1;
274   char *p;
275
276   if (strcmp(name->name,"*") == 0) {
277     /* special case for wildcard name */
278     memset(buf1,'\0',20);
279     buf1[0] = '*';
280     buf1[15] = name->name_type;
281   } else {
282     slprintf(buf1, sizeof(buf1) - 1,"%-15.15s%c",name->name,name->name_type);
283   }
284
285   buf[offset] = 0x20;
286
287   ret = 34;
288
289   for (m=0;m<16;m++) {
290     buf[offset+1+2*m] = 'A' + ((buf1[m]>>4)&0xF);
291     buf[offset+2+2*m] = 'A' + (buf1[m]&0xF);
292   }
293   offset += 33;
294
295   buf[offset] = 0;
296
297   if (name->scope[0]) {
298     /* XXXX this scope handling needs testing */
299     ret += strlen(name->scope) + 1;
300     pstrcpy(&buf[offset+1],name->scope);  
301   
302     p = &buf[offset+1];
303     while ((p = strchr(p,'.'))) {
304       buf[offset] = PTR_DIFF(p,&buf[offset]);
305       offset += buf[offset];
306       p = &buf[offset+1];
307     }
308     buf[offset] = strlen(&buf[offset+1]);
309   }
310
311   return(ret);
312 }
313
314 /*******************************************************************
315   useful for debugging messages
316   ******************************************************************/
317 char *nmb_namestr(struct nmb_name *n)
318 {
319   static int i=0;
320   static fstring ret[4];
321   char *p = ret[i];
322
323   if (!n->scope[0])
324     slprintf(p,sizeof(fstring)-1, "%s<%02x>",n->name,n->name_type);
325   else
326     slprintf(p,sizeof(fstring)-1, "%s<%02x>.%s",n->name,n->name_type,n->scope);
327
328   i = (i+1)%4;
329   return(p);
330 }
331
332 /*******************************************************************
333   allocate and parse some resource records
334   ******************************************************************/
335 static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length,
336                                 struct res_rec **recs, int count)
337 {
338   int i;
339   *recs = (struct res_rec *)malloc(sizeof(**recs)*count);
340   if (!*recs) return(False);
341
342   memset((char *)*recs,'\0',sizeof(**recs)*count);
343
344   for (i=0;i<count;i++) {
345     int l = parse_nmb_name(inbuf,*offset,length,&(*recs)[i].rr_name);
346     (*offset) += l;
347     if (!l || (*offset)+10 > length) {
348       free(*recs);
349       *recs = NULL;
350       return(False);
351     }
352     (*recs)[i].rr_type = RSVAL(inbuf,(*offset));
353     (*recs)[i].rr_class = RSVAL(inbuf,(*offset)+2);
354     (*recs)[i].ttl = RIVAL(inbuf,(*offset)+4);
355     (*recs)[i].rdlength = RSVAL(inbuf,(*offset)+8);
356     (*offset) += 10;
357     if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) || 
358         (*offset)+(*recs)[i].rdlength > length) {
359       free(*recs);
360       *recs = NULL;
361       return(False);
362     }
363     memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength);
364     (*offset) += (*recs)[i].rdlength;    
365   }
366   return(True);
367 }
368
369 /*******************************************************************
370   put a resource record into a packet
371   ******************************************************************/
372 static int put_res_rec(char *buf,int offset,struct res_rec *recs,int count)
373 {
374   int ret=0;
375   int i;
376
377   for (i=0;i<count;i++) {
378     int l = put_nmb_name(buf,offset,&recs[i].rr_name);
379     offset += l;
380     ret += l;
381     RSSVAL(buf,offset,recs[i].rr_type);
382     RSSVAL(buf,offset+2,recs[i].rr_class);
383     RSIVAL(buf,offset+4,recs[i].ttl);
384     RSSVAL(buf,offset+8,recs[i].rdlength);
385     memcpy(buf+offset+10,recs[i].rdata,recs[i].rdlength);
386     offset += 10+recs[i].rdlength;
387     ret += 10+recs[i].rdlength;
388   }
389
390   return(ret);
391 }
392
393 /*******************************************************************
394   put a compressed name pointer record into a packet
395   ******************************************************************/
396 static int put_compressed_name_ptr(unsigned char *buf,int offset,struct res_rec *rec,int ptr_offset)
397 {  
398   int ret=0;
399   buf[offset] = (0xC0 | ((ptr_offset >> 8) & 0xFF));
400   buf[offset+1] = (ptr_offset & 0xFF);
401   offset += 2;
402   ret += 2;
403   RSSVAL(buf,offset,rec->rr_type);
404   RSSVAL(buf,offset+2,rec->rr_class);
405   RSIVAL(buf,offset+4,rec->ttl);
406   RSSVAL(buf,offset+8,rec->rdlength);
407   memcpy(buf+offset+10,rec->rdata,rec->rdlength);
408   offset += 10+rec->rdlength;
409   ret += 10+rec->rdlength;
410     
411   return(ret);
412 }
413
414 /*******************************************************************
415   parse a dgram packet. Return False if the packet can't be parsed 
416   or is invalid for some reason, True otherwise 
417
418   this is documented in section 4.4.1 of RFC1002
419   ******************************************************************/
420 static BOOL parse_dgram(char *inbuf,int length,struct dgram_packet *dgram)
421 {
422   int offset;
423   int flags;
424
425   memset((char *)dgram,'\0',sizeof(*dgram));
426
427   if (length < 14) return(False);
428
429   dgram->header.msg_type = CVAL(inbuf,0);
430   flags = CVAL(inbuf,1);
431   dgram->header.flags.node_type = (enum node_type)((flags>>2)&3);
432   if (flags & 1) dgram->header.flags.more = True;
433   if (flags & 2) dgram->header.flags.first = True;
434   dgram->header.dgm_id = RSVAL(inbuf,2);
435   putip((char *)&dgram->header.source_ip,inbuf+4);
436   dgram->header.source_port = RSVAL(inbuf,8);
437   dgram->header.dgm_length = RSVAL(inbuf,10);
438   dgram->header.packet_offset = RSVAL(inbuf,12);
439
440   offset = 14;
441
442   if (dgram->header.msg_type == 0x10 ||
443       dgram->header.msg_type == 0x11 ||
444       dgram->header.msg_type == 0x12) {      
445     offset += parse_nmb_name(inbuf,offset,length,&dgram->source_name);
446     offset += parse_nmb_name(inbuf,offset,length,&dgram->dest_name);
447   }
448
449   if (offset >= length || (length-offset > sizeof(dgram->data))) 
450     return(False);
451
452   dgram->datasize = length-offset;
453   memcpy(dgram->data,inbuf+offset,dgram->datasize);
454
455   return(True);
456 }
457
458
459 /*******************************************************************
460   parse a nmb packet. Return False if the packet can't be parsed 
461   or is invalid for some reason, True otherwise 
462   ******************************************************************/
463 static BOOL parse_nmb(char *inbuf,int length,struct nmb_packet *nmb)
464 {
465   int nm_flags,offset;
466
467   memset((char *)nmb,'\0',sizeof(*nmb));
468
469   if (length < 12) return(False);
470
471   /* parse the header */
472   nmb->header.name_trn_id = RSVAL(inbuf,0);
473
474   DEBUG(10,("parse_nmb: packet id = %d\n", nmb->header.name_trn_id));
475
476   nmb->header.opcode = (CVAL(inbuf,2) >> 3) & 0xF;
477   nmb->header.response = ((CVAL(inbuf,2)>>7)&1)?True:False;
478   nm_flags = ((CVAL(inbuf,2) & 0x7) << 4) + (CVAL(inbuf,3)>>4);
479   nmb->header.nm_flags.bcast = (nm_flags&1)?True:False;
480   nmb->header.nm_flags.recursion_available = (nm_flags&8)?True:False;
481   nmb->header.nm_flags.recursion_desired = (nm_flags&0x10)?True:False;
482   nmb->header.nm_flags.trunc = (nm_flags&0x20)?True:False;
483   nmb->header.nm_flags.authoritative = (nm_flags&0x40)?True:False;  
484   nmb->header.rcode = CVAL(inbuf,3) & 0xF;
485   nmb->header.qdcount = RSVAL(inbuf,4);
486   nmb->header.ancount = RSVAL(inbuf,6);
487   nmb->header.nscount = RSVAL(inbuf,8);
488   nmb->header.arcount = RSVAL(inbuf,10);
489   
490   if (nmb->header.qdcount) {
491     offset = parse_nmb_name(inbuf,12,length,&nmb->question.question_name);
492     if (!offset) return(False);
493
494     if (length - (12+offset) < 4) return(False);
495     nmb->question.question_type = RSVAL(inbuf,12+offset);
496     nmb->question.question_class = RSVAL(inbuf,12+offset+2);
497
498     offset += 12+4;
499   } else {
500     offset = 12;
501   }
502
503   /* and any resource records */
504   if (nmb->header.ancount && 
505       !parse_alloc_res_rec(inbuf,&offset,length,&nmb->answers,
506                            nmb->header.ancount))
507     return(False);
508
509   if (nmb->header.nscount && 
510       !parse_alloc_res_rec(inbuf,&offset,length,&nmb->nsrecs,
511                            nmb->header.nscount))
512     return(False);
513   
514   if (nmb->header.arcount && 
515       !parse_alloc_res_rec(inbuf,&offset,length,&nmb->additional,
516                            nmb->header.arcount))
517     return(False);
518
519   return(True);
520 }
521
522 /*******************************************************************
523   'Copy constructor' for an nmb packet
524   ******************************************************************/
525 static struct packet_struct *copy_nmb_packet(struct packet_struct *packet)
526 {  
527   struct nmb_packet *nmb;
528   struct nmb_packet *copy_nmb;
529   struct packet_struct *pkt_copy;
530
531   if(( pkt_copy = (struct packet_struct *)malloc(sizeof(*packet))) == NULL)
532   {
533     DEBUG(0,("copy_nmb_packet: malloc fail.\n"));
534     return NULL;
535   }
536
537   /* Structure copy of entire thing. */
538
539   *pkt_copy = *packet;
540
541   /* Ensure this copy is not locked. */
542   pkt_copy->locked = False;
543
544   /* Ensure this copy has no resource records. */
545   nmb = &packet->packet.nmb;
546   copy_nmb = &pkt_copy->packet.nmb;
547
548   copy_nmb->answers = NULL;
549   copy_nmb->nsrecs = NULL;
550   copy_nmb->additional = NULL;
551
552   /* Now copy any resource records. */
553
554   if (nmb->answers)
555   {
556     if((copy_nmb->answers = (struct res_rec *)
557                   malloc(nmb->header.ancount * sizeof(struct res_rec))) == NULL)
558       goto free_and_exit;
559     memcpy((char *)copy_nmb->answers, (char *)nmb->answers, 
560            nmb->header.ancount * sizeof(struct res_rec));
561   }
562   if (nmb->nsrecs)
563   {
564     if((copy_nmb->nsrecs = (struct res_rec *)
565                   malloc(nmb->header.nscount * sizeof(struct res_rec))) == NULL)
566       goto free_and_exit;
567     memcpy((char *)copy_nmb->nsrecs, (char *)nmb->nsrecs, 
568            nmb->header.nscount * sizeof(struct res_rec));
569   }
570   if (nmb->additional)
571   {
572     if((copy_nmb->additional = (struct res_rec *)
573                   malloc(nmb->header.arcount * sizeof(struct res_rec))) == NULL)
574       goto free_and_exit;
575     memcpy((char *)copy_nmb->additional, (char *)nmb->additional, 
576            nmb->header.arcount * sizeof(struct res_rec));
577   }
578
579   return pkt_copy;
580
581 free_and_exit:
582
583   if(copy_nmb->answers) {
584     free((char *)copy_nmb->answers);
585     copy_nmb->answers = NULL;
586   }
587   if(copy_nmb->nsrecs) {
588     free((char *)copy_nmb->nsrecs);
589     copy_nmb->nsrecs = NULL;
590   }
591   if(copy_nmb->additional) {
592     free((char *)copy_nmb->additional);
593     copy_nmb->additional = NULL;
594   }
595   free((char *)pkt_copy);
596
597   DEBUG(0,("copy_nmb_packet: malloc fail in resource records.\n"));
598   return NULL;
599 }
600
601 /*******************************************************************
602   'Copy constructor' for a dgram packet
603   ******************************************************************/
604 static struct packet_struct *copy_dgram_packet(struct packet_struct *packet)
605
606   struct packet_struct *pkt_copy;
607
608   if(( pkt_copy = (struct packet_struct *)malloc(sizeof(*packet))) == NULL)
609   {
610     DEBUG(0,("copy_dgram_packet: malloc fail.\n"));
611     return NULL;
612   }
613
614   /* Structure copy of entire thing. */
615
616   *pkt_copy = *packet;
617
618   /* Ensure this copy is not locked. */
619   pkt_copy->locked = False;
620
621   /* There are no additional pointers in a dgram packet,
622      we are finished. */
623   return pkt_copy;
624 }
625
626 /*******************************************************************
627   'Copy constructor' for a generic packet
628   ******************************************************************/
629 struct packet_struct *copy_packet(struct packet_struct *packet)
630 {  
631   if(packet->packet_type == NMB_PACKET)
632     return copy_nmb_packet(packet);
633   else if (packet->packet_type == DGRAM_PACKET)
634     return copy_dgram_packet(packet);
635   return NULL;
636 }
637  
638 /*******************************************************************
639   free up any resources associated with an nmb packet
640   ******************************************************************/
641 static void free_nmb_packet(struct nmb_packet *nmb)
642 {  
643   if (nmb->answers) {
644     free(nmb->answers);
645     nmb->answers = NULL;
646   }
647   if (nmb->nsrecs) {
648     free(nmb->nsrecs);
649     nmb->nsrecs = NULL;
650   }
651   if (nmb->additional) {
652     free(nmb->additional);
653     nmb->additional = NULL;
654   }
655 }
656
657 /*******************************************************************
658   free up any resources associated with a dgram packet
659   ******************************************************************/
660 static void free_dgram_packet(struct dgram_packet *nmb)
661 {  
662   /* We have nothing to do for a dgram packet. */
663 }
664
665 /*******************************************************************
666   free up any resources associated with a packet
667   ******************************************************************/
668 void free_packet(struct packet_struct *packet)
669 {  
670   if (packet->locked) 
671     return;
672   if (packet->packet_type == NMB_PACKET)
673     free_nmb_packet(&packet->packet.nmb);
674   else if (packet->packet_type == DGRAM_PACKET)
675     free_dgram_packet(&packet->packet.dgram);
676   ZERO_STRUCTPN(packet);
677   free(packet);
678 }
679
680 /*******************************************************************
681 parse a packet buffer into a packet structure
682   ******************************************************************/
683 struct packet_struct *parse_packet(char *buf,int length,
684                                    enum packet_type packet_type)
685 {
686         extern struct in_addr lastip;
687         extern int lastport;
688         struct packet_struct *p;
689         BOOL ok=False;
690
691         p = (struct packet_struct *)malloc(sizeof(*p));
692         if (!p) return(NULL);
693
694         p->next = NULL;
695         p->prev = NULL;
696         p->ip = lastip;
697         p->port = lastport;
698         p->locked = False;
699         p->timestamp = time(NULL);
700         p->packet_type = packet_type;
701
702         switch (packet_type) {
703         case NMB_PACKET:
704                 ok = parse_nmb(buf,length,&p->packet.nmb);
705                 break;
706                 
707         case DGRAM_PACKET:
708                 ok = parse_dgram(buf,length,&p->packet.dgram);
709                 break;
710         }
711
712         if (!ok) {
713                 free_packet(p);
714                 return NULL;
715         }
716
717         return p;
718 }
719
720 /*******************************************************************
721   read a packet from a socket and parse it, returning a packet ready
722   to be used or put on the queue. This assumes a UDP socket
723   ******************************************************************/
724 struct packet_struct *read_packet(int fd,enum packet_type packet_type)
725 {
726         struct packet_struct *packet;
727         char buf[MAX_DGRAM_SIZE];
728         int length;
729         
730         length = read_udp_socket(fd,buf,sizeof(buf));
731         if (length < MIN_DGRAM_SIZE) return(NULL);
732         
733         packet = parse_packet(buf, length, packet_type);
734         if (!packet) return NULL;
735
736         packet->fd = fd;
737         
738         num_good_receives++;
739         
740         DEBUG(5,("Received a packet of len %d from (%s) port %d\n",
741                  length, inet_ntoa(packet->ip), packet->port ) );
742         
743         return(packet);
744 }
745                                          
746
747 /*******************************************************************
748   send a udp packet on a already open socket
749   ******************************************************************/
750 static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port)
751 {
752   BOOL ret;
753   struct sockaddr_in sock_out;
754
755   /* set the address and port */
756   memset((char *)&sock_out,'\0',sizeof(sock_out));
757   putip((char *)&sock_out.sin_addr,(char *)&ip);
758   sock_out.sin_port = htons( port );
759   sock_out.sin_family = AF_INET;
760   
761   DEBUG( 5, ( "Sending a packet of len %d to (%s) on port %d\n",
762               len, inet_ntoa(ip), port ) );
763         
764   ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out,
765                 sizeof(sock_out)) >= 0);
766
767   if (!ret)
768     DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n",
769              inet_ntoa(ip),port,strerror(errno)));
770
771   if (ret)
772     num_good_sends++;
773
774   return(ret);
775 }
776
777 /*******************************************************************
778   build a dgram packet ready for sending
779
780   XXXX This currently doesn't handle packets too big for one
781   datagram. It should split them and use the packet_offset, more and
782   first flags to handle the fragmentation. Yuck.
783   ******************************************************************/
784 static int build_dgram(char *buf,struct packet_struct *p)
785 {
786   struct dgram_packet *dgram = &p->packet.dgram;
787   unsigned char *ubuf = (unsigned char *)buf;
788   int offset=0;
789
790   /* put in the header */
791   ubuf[0] = dgram->header.msg_type;
792   ubuf[1] = (((int)dgram->header.flags.node_type)<<2);
793   if (dgram->header.flags.more) ubuf[1] |= 1;
794   if (dgram->header.flags.first) ubuf[1] |= 2;
795   RSSVAL(ubuf,2,dgram->header.dgm_id);
796   putip(ubuf+4,(char *)&dgram->header.source_ip);
797   RSSVAL(ubuf,8,dgram->header.source_port);
798   RSSVAL(ubuf,12,dgram->header.packet_offset);
799
800   offset = 14;
801
802   if (dgram->header.msg_type == 0x10 ||
803       dgram->header.msg_type == 0x11 ||
804       dgram->header.msg_type == 0x12) {      
805     offset += put_nmb_name((char *)ubuf,offset,&dgram->source_name);
806     offset += put_nmb_name((char *)ubuf,offset,&dgram->dest_name);
807   }
808
809   memcpy(ubuf+offset,dgram->data,dgram->datasize);
810   offset += dgram->datasize;
811
812   /* automatically set the dgm_length */
813   dgram->header.dgm_length = offset;
814   RSSVAL(ubuf,10,dgram->header.dgm_length); 
815
816   return(offset);
817 }
818
819 /*******************************************************************
820   build a nmb name
821  *******************************************************************/
822 void make_nmb_name( struct nmb_name *n, const char *name, int type)
823 {
824         extern pstring global_scope;
825         memset( (char *)n, '\0', sizeof(struct nmb_name) );
826         StrnCpy( n->name, name, 15 );
827         strupper( n->name );
828         n->name_type = (unsigned int)type & 0xFF;
829         StrnCpy( n->scope, global_scope, 63 );
830         strupper( n->scope );
831 }
832
833 /*******************************************************************
834   Compare two nmb names
835   ******************************************************************/
836
837 BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2)
838 {
839   return ((n1->name_type == n2->name_type) &&
840          strequal(n1->name ,n2->name ) &&
841          strequal(n1->scope,n2->scope));
842 }
843
844 /*******************************************************************
845   build a nmb packet ready for sending
846
847   XXXX this currently relies on not being passed something that expands
848   to a packet too big for the buffer. Eventually this should be
849   changed to set the trunc bit so the receiver can request the rest
850   via tcp (when that becomes supported)
851   ******************************************************************/
852 static int build_nmb(char *buf,struct packet_struct *p)
853 {
854   struct nmb_packet *nmb = &p->packet.nmb;
855   unsigned char *ubuf = (unsigned char *)buf;
856   int offset=0;
857
858   /* put in the header */
859   RSSVAL(ubuf,offset,nmb->header.name_trn_id);
860   ubuf[offset+2] = (nmb->header.opcode & 0xF) << 3;
861   if (nmb->header.response) ubuf[offset+2] |= (1<<7);
862   if (nmb->header.nm_flags.authoritative && 
863       nmb->header.response) ubuf[offset+2] |= 0x4;
864   if (nmb->header.nm_flags.trunc) ubuf[offset+2] |= 0x2;
865   if (nmb->header.nm_flags.recursion_desired) ubuf[offset+2] |= 0x1;
866   if (nmb->header.nm_flags.recursion_available &&
867       nmb->header.response) ubuf[offset+3] |= 0x80;
868   if (nmb->header.nm_flags.bcast) ubuf[offset+3] |= 0x10;
869   ubuf[offset+3] |= (nmb->header.rcode & 0xF);
870
871   RSSVAL(ubuf,offset+4,nmb->header.qdcount);
872   RSSVAL(ubuf,offset+6,nmb->header.ancount);
873   RSSVAL(ubuf,offset+8,nmb->header.nscount);
874   RSSVAL(ubuf,offset+10,nmb->header.arcount);
875   
876   offset += 12;
877   if (nmb->header.qdcount) {
878     /* XXXX this doesn't handle a qdcount of > 1 */
879     offset += put_nmb_name((char *)ubuf,offset,&nmb->question.question_name);
880     RSSVAL(ubuf,offset,nmb->question.question_type);
881     RSSVAL(ubuf,offset+2,nmb->question.question_class);
882     offset += 4;
883   }
884
885   if (nmb->header.ancount)
886     offset += put_res_rec((char *)ubuf,offset,nmb->answers,
887                           nmb->header.ancount);
888
889   if (nmb->header.nscount)
890     offset += put_res_rec((char *)ubuf,offset,nmb->nsrecs,
891                           nmb->header.nscount);
892
893   /*
894    * The spec says we must put compressed name pointers
895    * in the following outgoing packets :
896    * NAME_REGISTRATION_REQUEST, NAME_REFRESH_REQUEST,
897    * NAME_RELEASE_REQUEST.
898    */
899
900   if((nmb->header.response == False) &&
901      ((nmb->header.opcode == NMB_NAME_REG_OPCODE) ||
902       (nmb->header.opcode == NMB_NAME_RELEASE_OPCODE) ||
903       (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_8) ||
904       (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_9) ||
905       (nmb->header.opcode == NMB_NAME_MULTIHOMED_REG_OPCODE)) &&
906      (nmb->header.arcount == 1)) {
907
908     offset += put_compressed_name_ptr(ubuf,offset,nmb->additional,12);
909
910   } else if (nmb->header.arcount) {
911     offset += put_res_rec((char *)ubuf,offset,nmb->additional,
912                           nmb->header.arcount);  
913   }
914   return(offset);
915 }
916
917
918 /*******************************************************************
919 linearise a packet
920   ******************************************************************/
921 int build_packet(char *buf, struct packet_struct *p)
922 {
923         int len = 0;
924
925         switch (p->packet_type) {
926         case NMB_PACKET:
927                 len = build_nmb(buf,p);
928                 break;
929
930         case DGRAM_PACKET:
931                 len = build_dgram(buf,p);
932                 break;
933         }
934
935         return len;
936 }
937
938 /*******************************************************************
939   send a packet_struct
940   ******************************************************************/
941 BOOL send_packet(struct packet_struct *p)
942 {
943   char buf[1024];
944   int len=0;
945
946   memset(buf,'\0',sizeof(buf));
947
948   len = build_packet(buf, p);
949
950   if (!len) return(False);
951
952   return(send_udp(p->fd,buf,len,p->ip,p->port));
953 }
954
955 /****************************************************************************
956   receive a packet with timeout on a open UDP filedescriptor
957   The timeout is in milliseconds
958   ***************************************************************************/
959 struct packet_struct *receive_packet(int fd,enum packet_type type,int t)
960 {
961         fd_set fds;
962         struct timeval timeout;
963
964         FD_ZERO(&fds);
965         FD_SET(fd,&fds);
966         timeout.tv_sec = t/1000;
967         timeout.tv_usec = 1000*(t%1000);
968
969         sys_select(fd+1,&fds,&timeout);
970
971         if (FD_ISSET(fd,&fds)) 
972                 return(read_packet(fd,type));
973         
974         return(NULL);
975 }
976
977
978 /****************************************************************************
979   receive a UDP/137 packet either via UDP or from the unexpected packet
980   queue. The packet must be a reply packet and have the specified trn_id
981   The timeout is in milliseconds
982   ***************************************************************************/
983 struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id)
984 {
985         struct packet_struct *p;
986
987         p = receive_packet(fd, NMB_PACKET, t);
988
989         if (p && p->packet.nmb.header.response &&
990             p->packet.nmb.header.name_trn_id == trn_id) {
991                 return p;
992         }
993         if (p) free_packet(p);
994
995         /* try the unexpected packet queue */
996         return receive_unexpected(NMB_PACKET, trn_id, NULL);
997 }
998
999 /****************************************************************************
1000   receive a UDP/138 packet either via UDP or from the unexpected packet
1001   queue. The packet must be a reply packet and have the specified mailslot name
1002   The timeout is in milliseconds
1003   ***************************************************************************/
1004 struct packet_struct *receive_dgram_packet(int fd, int t, char *mailslot_name)
1005 {
1006         struct packet_struct *p;
1007
1008         p = receive_packet(fd, DGRAM_PACKET, t);
1009
1010         if (p && match_mailslot_name(p, mailslot_name)) {
1011                 return p;
1012         }
1013         if (p) free_packet(p);
1014
1015         /* try the unexpected packet queue */
1016         return receive_unexpected(DGRAM_PACKET, 0, mailslot_name);
1017 }
1018
1019
1020 /****************************************************************************
1021  see if a datagram has the right mailslot name
1022 ***************************************************************************/
1023 BOOL match_mailslot_name(struct packet_struct *p, char *mailslot_name)
1024 {
1025         struct dgram_packet *dgram = &p->packet.dgram;
1026         char *buf;
1027
1028         buf = &dgram->data[0];
1029         buf -= 4;
1030
1031         buf = smb_buf(buf);
1032
1033         if (memcmp(buf, mailslot_name, strlen(mailslot_name)+1) == 0) {
1034                 return True;
1035         }
1036
1037         return False;
1038 }
1039
1040
1041 /****************************************************************************
1042 return the number of bits that match between two 4 character buffers
1043   ***************************************************************************/
1044 static int matching_bits(uchar *p1, uchar *p2)
1045 {
1046         int i, j, ret = 0;
1047         for (i=0; i<4; i++) {
1048                 if (p1[i] != p2[i]) break;
1049                 ret += 8;
1050         }
1051
1052         if (i==4) return ret;
1053
1054         for (j=0; j<8; j++) {
1055                 if ((p1[i] & (1<<(7-j))) != (p2[i] & (1<<(7-j)))) break;
1056                 ret++;
1057         }       
1058         
1059         return ret;
1060 }
1061
1062
1063 static uchar sort_ip[4];
1064
1065 /****************************************************************************
1066 compare two query reply records
1067   ***************************************************************************/
1068 static int name_query_comp(uchar *p1, uchar *p2)
1069 {
1070         return matching_bits(p2+2, sort_ip) - matching_bits(p1+2, sort_ip);
1071 }
1072
1073 /****************************************************************************
1074 sort a set of 6 byte name query response records so that the IPs that
1075 have the most leading bits in common with the specified address come first
1076   ***************************************************************************/
1077 void sort_query_replies(char *data, int n, struct in_addr ip)
1078 {
1079         if (n <= 1) return;
1080
1081         putip(sort_ip, (char *)&ip);
1082
1083         qsort(data, n, 6, QSORT_CAST name_query_comp);
1084 }