tridge the destroyer returns!
[samba.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                  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                      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
183   if (length - offset < 2) return(0);  
184
185   /* handle initial name pointers */
186   if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) return(0);
187   
188   m = ubuf[offset];
189
190   if (!m) return(0);
191   if ((m & 0xC0) || offset+m+2 > length) return(0);
192
193   bzero((char *)name,sizeof(*name));
194
195   /* the "compressed" part */
196   if (!got_pointer) ret += m + 2;
197   offset++;
198   while (m) {
199     unsigned char c1,c2;
200     c1 = ubuf[offset++]-'A';
201     c2 = ubuf[offset++]-'A';
202     if ((c1 & 0xF0) || (c2 & 0xF0) || (n > sizeof(name->name)-1)) return(0);
203     name->name[n++] = (c1<<4) | c2;
204     m -= 2;
205   }
206   name->name[n] = 0;
207
208   if (n==16) {
209     /* parse out the name type, 
210        its always in the 16th byte of the name */
211     name->name_type = ((unsigned char)name->name[15]) & 0xff;
212   
213     /* remove trailing spaces */
214     name->name[15] = 0;
215     n = 14;
216     while (n && name->name[n]==' ') name->name[n--] = 0;  
217   }
218
219   /* now the domain parts (if any) */
220   n = 0;
221   while ((m=ubuf[offset])) {
222     /* we can have pointers within the domain part as well */
223     if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) return(0);
224
225     if (!got_pointer) ret += m+1;
226     if (n) name->scope[n++] = '.';
227     if (m+2+offset>length || n+m+1>sizeof(name->scope)) return(0);
228     offset++;
229     while (m--) name->scope[n++] = (char)ubuf[offset++];
230   }
231   name->scope[n++] = 0;  
232
233   return(ret);
234 }
235
236
237 /*******************************************************************
238   put a compressed nmb name into a buffer. return the length of the
239   compressed name
240
241   compressed names are really weird. The "compression" doubles the
242   size. The idea is that it also means that compressed names conform
243   to the doman name system. See RFC1002.
244   ******************************************************************/
245 static int put_nmb_name(char *buf,int offset,struct nmb_name *name)
246 {
247   int ret,m;
248   fstring buf1;
249   char *p;
250
251   if (name->name[0] == '*') {
252     /* special case for wildcard name */
253     bzero(buf1,20);
254     buf1[0] = '*';
255     buf1[15] = name->name_type;
256   } else {
257     slprintf(buf1, sizeof(buf1) - 1,"%-15.15s%c",name->name,name->name_type);
258   }
259
260   buf[offset] = 0x20;
261
262   ret = 34;
263
264   for (m=0;m<16;m++) {
265     buf[offset+1+2*m] = 'A' + ((buf1[m]>>4)&0xF);
266     buf[offset+2+2*m] = 'A' + (buf1[m]&0xF);
267   }
268   offset += 33;
269
270   buf[offset] = 0;
271
272   if (name->scope[0]) {
273     /* XXXX this scope handling needs testing */
274     ret += strlen(name->scope) + 1;
275     pstrcpy(&buf[offset+1],name->scope);  
276   
277     p = &buf[offset+1];
278     while ((p = strchr(p,'.'))) {
279       buf[offset] = PTR_DIFF(p,&buf[offset]);
280       offset += buf[offset];
281       p = &buf[offset+1];
282     }
283     buf[offset] = strlen(&buf[offset+1]);
284   }
285
286   return(ret);
287 }
288
289 /*******************************************************************
290   useful for debugging messages
291   ******************************************************************/
292 char *namestr(struct nmb_name *n)
293 {
294   static int i=0;
295   static fstring ret[4];
296   char *p = ret[i];
297
298   if (!n->scope[0])
299     slprintf(p,sizeof(fstring)-1, "%s<%02x>",n->name,n->name_type);
300   else
301     slprintf(p,sizeof(fstring)-1, "%s<%02x>.%s",n->name,n->name_type,n->scope);
302
303   i = (i+1)%4;
304   return(p);
305 }
306
307 /*******************************************************************
308   allocate and parse some resource records
309   ******************************************************************/
310 static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length,
311                                 struct res_rec **recs, int count)
312 {
313   int i;
314   *recs = (struct res_rec *)malloc(sizeof(**recs)*count);
315   if (!*recs) return(False);
316
317   bzero(*recs,sizeof(**recs)*count);
318
319   for (i=0;i<count;i++) {
320     int l = parse_nmb_name(inbuf,*offset,length,&(*recs)[i].rr_name);
321     (*offset) += l;
322     if (!l || (*offset)+10 > length) {
323       free(*recs);
324       return(False);
325     }
326     (*recs)[i].rr_type = RSVAL(inbuf,(*offset));
327     (*recs)[i].rr_class = RSVAL(inbuf,(*offset)+2);
328     (*recs)[i].ttl = RIVAL(inbuf,(*offset)+4);
329     (*recs)[i].rdlength = RSVAL(inbuf,(*offset)+8);
330     (*offset) += 10;
331     if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) || 
332         (*offset)+(*recs)[i].rdlength > length) {
333       free(*recs);
334       return(False);
335     }
336     memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength);
337     (*offset) += (*recs)[i].rdlength;    
338   }
339   return(True);
340 }
341
342 /*******************************************************************
343   put a resource record into a packet
344   ******************************************************************/
345 static int put_res_rec(char *buf,int offset,struct res_rec *recs,int count)
346 {
347   int ret=0;
348   int i;
349
350   for (i=0;i<count;i++) {
351     int l = put_nmb_name(buf,offset,&recs[i].rr_name);
352     offset += l;
353     ret += l;
354     RSSVAL(buf,offset,recs[i].rr_type);
355     RSSVAL(buf,offset+2,recs[i].rr_class);
356     RSIVAL(buf,offset+4,recs[i].ttl);
357     RSSVAL(buf,offset+8,recs[i].rdlength);
358     memcpy(buf+offset+10,recs[i].rdata,recs[i].rdlength);
359     offset += 10+recs[i].rdlength;
360     ret += 10+recs[i].rdlength;
361   }
362
363   return(ret);
364 }
365
366 /*******************************************************************
367   put a compressed name pointer record into a packet
368   ******************************************************************/
369 static int put_compressed_name_ptr(unsigned char *buf,int offset,struct res_rec *rec,int ptr_offset)
370 {  
371   int ret=0;
372   buf[offset] = (0xC0 | ((ptr_offset >> 8) & 0xFF));
373   buf[offset+1] = (ptr_offset & 0xFF);
374   offset += 2;
375   ret += 2;
376   RSSVAL(buf,offset,rec->rr_type);
377   RSSVAL(buf,offset+2,rec->rr_class);
378   RSIVAL(buf,offset+4,rec->ttl);
379   RSSVAL(buf,offset+8,rec->rdlength);
380   memcpy(buf+offset+10,rec->rdata,rec->rdlength);
381   offset += 10+rec->rdlength;
382   ret += 10+rec->rdlength;
383     
384   return(ret);
385 }
386
387 /*******************************************************************
388   parse a dgram packet. Return False if the packet can't be parsed 
389   or is invalid for some reason, True otherwise 
390
391   this is documented in section 4.4.1 of RFC1002
392   ******************************************************************/
393 static BOOL parse_dgram(char *inbuf,int length,struct dgram_packet *dgram)
394 {
395   int offset;
396   int flags;
397
398   bzero((char *)dgram,sizeof(*dgram));
399
400   if (length < 14) return(False);
401
402   dgram->header.msg_type = CVAL(inbuf,0);
403   flags = CVAL(inbuf,1);
404   dgram->header.flags.node_type = (enum node_type)((flags>>2)&3);
405   if (flags & 1) dgram->header.flags.more = True;
406   if (flags & 2) dgram->header.flags.first = True;
407   dgram->header.dgm_id = RSVAL(inbuf,2);
408   putip((char *)&dgram->header.source_ip,inbuf+4);
409   dgram->header.source_port = RSVAL(inbuf,8);
410   dgram->header.dgm_length = RSVAL(inbuf,10);
411   dgram->header.packet_offset = RSVAL(inbuf,12);
412
413   offset = 14;
414
415   if (dgram->header.msg_type == 0x10 ||
416       dgram->header.msg_type == 0x11 ||
417       dgram->header.msg_type == 0x12) {      
418     offset += parse_nmb_name(inbuf,offset,length,&dgram->source_name);
419     offset += parse_nmb_name(inbuf,offset,length,&dgram->dest_name);
420   }
421
422   if (offset >= length || (length-offset > sizeof(dgram->data))) 
423     return(False);
424
425   dgram->datasize = length-offset;
426   memcpy(dgram->data,inbuf+offset,dgram->datasize);
427
428   return(True);
429 }
430
431
432 /*******************************************************************
433   parse a nmb packet. Return False if the packet can't be parsed 
434   or is invalid for some reason, True otherwise 
435   ******************************************************************/
436 static BOOL parse_nmb(char *inbuf,int length,struct nmb_packet *nmb)
437 {
438   int nm_flags,offset;
439
440   bzero((char *)nmb,sizeof(*nmb));
441
442   if (length < 12) return(False);
443
444   /* parse the header */
445   nmb->header.name_trn_id = RSVAL(inbuf,0);
446
447   DEBUG(10,("parse_nmb: packet id = %d\n", nmb->header.name_trn_id));
448
449   nmb->header.opcode = (CVAL(inbuf,2) >> 3) & 0xF;
450   nmb->header.response = ((CVAL(inbuf,2)>>7)&1)?True:False;
451   nm_flags = ((CVAL(inbuf,2) & 0x7) << 4) + (CVAL(inbuf,3)>>4);
452   nmb->header.nm_flags.bcast = (nm_flags&1)?True:False;
453   nmb->header.nm_flags.recursion_available = (nm_flags&8)?True:False;
454   nmb->header.nm_flags.recursion_desired = (nm_flags&0x10)?True:False;
455   nmb->header.nm_flags.trunc = (nm_flags&0x20)?True:False;
456   nmb->header.nm_flags.authoritative = (nm_flags&0x40)?True:False;  
457   nmb->header.rcode = CVAL(inbuf,3) & 0xF;
458   nmb->header.qdcount = RSVAL(inbuf,4);
459   nmb->header.ancount = RSVAL(inbuf,6);
460   nmb->header.nscount = RSVAL(inbuf,8);
461   nmb->header.arcount = RSVAL(inbuf,10);
462   
463   if (nmb->header.qdcount) {
464     offset = parse_nmb_name(inbuf,12,length,&nmb->question.question_name);
465     if (!offset) return(False);
466
467     if (length - (12+offset) < 4) return(False);
468     nmb->question.question_type = RSVAL(inbuf,12+offset);
469     nmb->question.question_class = RSVAL(inbuf,12+offset+2);
470
471     offset += 12+4;
472   } else {
473     offset = 12;
474   }
475
476   /* and any resource records */
477   if (nmb->header.ancount && 
478       !parse_alloc_res_rec(inbuf,&offset,length,&nmb->answers,
479                            nmb->header.ancount))
480     return(False);
481
482   if (nmb->header.nscount && 
483       !parse_alloc_res_rec(inbuf,&offset,length,&nmb->nsrecs,
484                            nmb->header.nscount))
485     return(False);
486   
487   if (nmb->header.arcount && 
488       !parse_alloc_res_rec(inbuf,&offset,length,&nmb->additional,
489                            nmb->header.arcount))
490     return(False);
491
492   return(True);
493 }
494
495 /*******************************************************************
496   'Copy constructor' for an nmb packet
497   ******************************************************************/
498 static struct packet_struct *copy_nmb_packet(struct packet_struct *packet)
499 {  
500   struct nmb_packet *nmb;
501   struct nmb_packet *copy_nmb;
502   struct packet_struct *pkt_copy;
503
504   if(( pkt_copy = (struct packet_struct *)malloc(sizeof(*packet))) == NULL)
505   {
506     DEBUG(0,("copy_nmb_packet: malloc fail.\n"));
507     return NULL;
508   }
509
510   /* Structure copy of entire thing. */
511
512   *pkt_copy = *packet;
513
514   /* Ensure this copy is not locked. */
515   pkt_copy->locked = False;
516
517   /* Ensure this copy has no resource records. */
518   nmb = &packet->packet.nmb;
519   copy_nmb = &pkt_copy->packet.nmb;
520
521   copy_nmb->answers = NULL;
522   copy_nmb->nsrecs = NULL;
523   copy_nmb->additional = NULL;
524
525   /* Now copy any resource records. */
526
527   if (nmb->answers)
528   {
529     if((copy_nmb->answers = (struct res_rec *)
530                   malloc(nmb->header.ancount * sizeof(struct res_rec))) == NULL)
531       goto free_and_exit;
532     memcpy((char *)copy_nmb->answers, (char *)nmb->answers, 
533            nmb->header.ancount * sizeof(struct res_rec));
534   }
535   if (nmb->nsrecs)
536   {
537     if((copy_nmb->nsrecs = (struct res_rec *)
538                   malloc(nmb->header.nscount * sizeof(struct res_rec))) == NULL)
539       goto free_and_exit;
540     memcpy((char *)copy_nmb->nsrecs, (char *)nmb->nsrecs, 
541            nmb->header.nscount * sizeof(struct res_rec));
542   }
543   if (nmb->additional)
544   {
545     if((copy_nmb->additional = (struct res_rec *)
546                   malloc(nmb->header.arcount * sizeof(struct res_rec))) == NULL)
547       goto free_and_exit;
548     memcpy((char *)copy_nmb->additional, (char *)nmb->additional, 
549            nmb->header.arcount * sizeof(struct res_rec));
550   }
551
552   return pkt_copy;
553
554 free_and_exit:
555
556   if(copy_nmb->answers)
557     free((char *)copy_nmb->answers);
558   if(copy_nmb->nsrecs)
559     free((char *)copy_nmb->nsrecs);
560   if(copy_nmb->additional)
561     free((char *)copy_nmb->additional);
562   free((char *)pkt_copy);
563
564   DEBUG(0,("copy_nmb_packet: malloc fail in resource records.\n"));
565   return NULL;
566 }
567
568 /*******************************************************************
569   'Copy constructor' for a dgram packet
570   ******************************************************************/
571 static struct packet_struct *copy_dgram_packet(struct packet_struct *packet)
572
573   struct packet_struct *pkt_copy;
574
575   if(( pkt_copy = (struct packet_struct *)malloc(sizeof(*packet))) == NULL)
576   {
577     DEBUG(0,("copy_dgram_packet: malloc fail.\n"));
578     return NULL;
579   }
580
581   /* Structure copy of entire thing. */
582
583   *pkt_copy = *packet;
584
585   /* Ensure this copy is not locked. */
586   pkt_copy->locked = False;
587
588   /* There are no additional pointers in a dgram packet,
589      we are finished. */
590   return pkt_copy;
591 }
592
593 /*******************************************************************
594   'Copy constructor' for a generic packet
595   ******************************************************************/
596 struct packet_struct *copy_packet(struct packet_struct *packet)
597 {  
598   if(packet->packet_type == NMB_PACKET)
599     return copy_nmb_packet(packet);
600   else if (packet->packet_type == DGRAM_PACKET)
601     return copy_dgram_packet(packet);
602   return NULL;
603 }
604  
605 /*******************************************************************
606   free up any resources associated with an nmb packet
607   ******************************************************************/
608 static void free_nmb_packet(struct nmb_packet *nmb)
609 {  
610   if (nmb->answers) free(nmb->answers);
611   if (nmb->nsrecs) free(nmb->nsrecs);
612   if (nmb->additional) free(nmb->additional);
613 }
614
615 /*******************************************************************
616   free up any resources associated with a dgram packet
617   ******************************************************************/
618 static void free_dgram_packet(struct dgram_packet *nmb)
619 {  
620   /* We have nothing to do for a dgram packet. */
621 }
622
623 /*******************************************************************
624   free up any resources associated with a packet
625   ******************************************************************/
626 void free_packet(struct packet_struct *packet)
627 {  
628   if (packet->locked) 
629     return;
630   if (packet->packet_type == NMB_PACKET)
631     free_nmb_packet(&packet->packet.nmb);
632   else if (packet->packet_type == DGRAM_PACKET)
633     free_dgram_packet(&packet->packet.dgram);
634   free(packet);
635 }
636
637 /*******************************************************************
638   read a packet from a socket and parse it, returning a packet ready
639   to be used or put on the queue. This assumes a UDP socket
640   ******************************************************************/
641 struct packet_struct *read_packet(int fd,enum packet_type packet_type)
642 {
643   extern struct in_addr lastip;
644   extern int lastport;
645   struct packet_struct *packet;
646   char buf[MAX_DGRAM_SIZE];
647   int length;
648   BOOL ok=False;
649   
650   length = read_udp_socket(fd,buf,sizeof(buf));
651   if (length < MIN_DGRAM_SIZE) return(NULL);
652
653   packet = (struct packet_struct *)malloc(sizeof(*packet));
654   if (!packet) return(NULL);
655
656   packet->next = NULL;
657   packet->prev = NULL;
658   packet->ip = lastip;
659   packet->port = lastport;
660   packet->fd = fd;
661   packet->locked = False;
662   packet->timestamp = time(NULL);
663   packet->packet_type = packet_type;
664   switch (packet_type) 
665     {
666     case NMB_PACKET:
667       ok = parse_nmb(buf,length,&packet->packet.nmb);
668       break;
669
670     case DGRAM_PACKET:
671       ok = parse_dgram(buf,length,&packet->packet.dgram);
672       break;
673     }
674   if (!ok) {
675     DEBUG(10,("parse_nmb: discarding packet id = %d\n", 
676                  packet->packet.nmb.header.name_trn_id));
677     free(packet);
678     return(NULL);
679   }
680
681   num_good_receives++;
682
683   DEBUG(5,("Received a packet of len %d from (%s) port %d\n",
684             length, inet_ntoa(packet->ip), packet->port ) );
685
686   return(packet);
687 }
688                                          
689
690 /*******************************************************************
691   send a udp packet on a already open socket
692   ******************************************************************/
693 static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port)
694 {
695   BOOL ret;
696   struct sockaddr_in sock_out;
697
698   /* set the address and port */
699   bzero((char *)&sock_out,sizeof(sock_out));
700   putip((char *)&sock_out.sin_addr,(char *)&ip);
701   sock_out.sin_port = htons( port );
702   sock_out.sin_family = AF_INET;
703   
704   DEBUG( 5, ( "Sending a packet of len %d to (%s) on port %d\n",
705               len, inet_ntoa(ip), port ) );
706         
707   ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out,
708                 sizeof(sock_out)) >= 0);
709
710   if (!ret)
711     DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n",
712              inet_ntoa(ip),port,strerror(errno)));
713
714   if (ret)
715     num_good_sends++;
716
717   return(ret);
718 }
719
720 /*******************************************************************
721   build a dgram packet ready for sending
722
723   XXXX This currently doesn't handle packets too big for one
724   datagram. It should split them and use the packet_offset, more and
725   first flags to handle the fragmentation. Yuck.
726   ******************************************************************/
727 static int build_dgram(char *buf,struct packet_struct *p)
728 {
729   struct dgram_packet *dgram = &p->packet.dgram;
730   unsigned char *ubuf = (unsigned char *)buf;
731   int offset=0;
732
733   /* put in the header */
734   ubuf[0] = dgram->header.msg_type;
735   ubuf[1] = (((int)dgram->header.flags.node_type)<<2);
736   if (dgram->header.flags.more) ubuf[1] |= 1;
737   if (dgram->header.flags.first) ubuf[1] |= 2;
738   RSSVAL(ubuf,2,dgram->header.dgm_id);
739   putip(ubuf+4,(char *)&dgram->header.source_ip);
740   RSSVAL(ubuf,8,dgram->header.source_port);
741   RSSVAL(ubuf,12,dgram->header.packet_offset);
742
743   offset = 14;
744
745   if (dgram->header.msg_type == 0x10 ||
746       dgram->header.msg_type == 0x11 ||
747       dgram->header.msg_type == 0x12) {      
748     offset += put_nmb_name((char *)ubuf,offset,&dgram->source_name);
749     offset += put_nmb_name((char *)ubuf,offset,&dgram->dest_name);
750   }
751
752   memcpy(ubuf+offset,dgram->data,dgram->datasize);
753   offset += dgram->datasize;
754
755   /* automatically set the dgm_length */
756   dgram->header.dgm_length = offset;
757   RSSVAL(ubuf,10,dgram->header.dgm_length); 
758
759   return(offset);
760 }
761
762 /*******************************************************************
763   build a nmb name
764  *******************************************************************/
765 void make_nmb_name( struct nmb_name *n, char *name, int type, char *this_scope )
766 {
767   memset( (char *)n, '\0', sizeof(struct nmb_name) );
768   StrnCpy( n->name, name, 15 );
769   strupper( n->name );
770   n->name_type = (unsigned int)type & 0xFF;
771   StrnCpy( n->scope, this_scope, 63 );
772   strupper( n->scope );
773 }
774
775 /*******************************************************************
776   Compare two nmb names
777   ******************************************************************/
778
779 BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2)
780 {
781   return ((n1->name_type == n2->name_type) &&
782          strequal(n1->name ,n2->name ) &&
783          strequal(n1->scope,n2->scope));
784 }
785
786 /*******************************************************************
787   build a nmb packet ready for sending
788
789   XXXX this currently relies on not being passed something that expands
790   to a packet too big for the buffer. Eventually this should be
791   changed to set the trunc bit so the receiver can request the rest
792   via tcp (when that becomes supported)
793   ******************************************************************/
794 static int build_nmb(char *buf,struct packet_struct *p)
795 {
796   struct nmb_packet *nmb = &p->packet.nmb;
797   unsigned char *ubuf = (unsigned char *)buf;
798   int offset=0;
799
800   /* put in the header */
801   RSSVAL(ubuf,offset,nmb->header.name_trn_id);
802   ubuf[offset+2] = (nmb->header.opcode & 0xF) << 3;
803   if (nmb->header.response) ubuf[offset+2] |= (1<<7);
804   if (nmb->header.nm_flags.authoritative && 
805       nmb->header.response) ubuf[offset+2] |= 0x4;
806   if (nmb->header.nm_flags.trunc) ubuf[offset+2] |= 0x2;
807   if (nmb->header.nm_flags.recursion_desired) ubuf[offset+2] |= 0x1;
808   if (nmb->header.nm_flags.recursion_available &&
809       nmb->header.response) ubuf[offset+3] |= 0x80;
810   if (nmb->header.nm_flags.bcast) ubuf[offset+3] |= 0x10;
811   ubuf[offset+3] |= (nmb->header.rcode & 0xF);
812
813   RSSVAL(ubuf,offset+4,nmb->header.qdcount);
814   RSSVAL(ubuf,offset+6,nmb->header.ancount);
815   RSSVAL(ubuf,offset+8,nmb->header.nscount);
816   RSSVAL(ubuf,offset+10,nmb->header.arcount);
817   
818   offset += 12;
819   if (nmb->header.qdcount) {
820     /* XXXX this doesn't handle a qdcount of > 1 */
821     offset += put_nmb_name((char *)ubuf,offset,&nmb->question.question_name);
822     RSSVAL(ubuf,offset,nmb->question.question_type);
823     RSSVAL(ubuf,offset+2,nmb->question.question_class);
824     offset += 4;
825   }
826
827   if (nmb->header.ancount)
828     offset += put_res_rec((char *)ubuf,offset,nmb->answers,
829                           nmb->header.ancount);
830
831   if (nmb->header.nscount)
832     offset += put_res_rec((char *)ubuf,offset,nmb->nsrecs,
833                           nmb->header.nscount);
834
835   /*
836    * The spec says we must put compressed name pointers
837    * in the following outgoing packets :
838    * NAME_REGISTRATION_REQUEST, NAME_REFRESH_REQUEST,
839    * NAME_RELEASE_REQUEST.
840    */
841
842   if((nmb->header.response == False) &&
843      ((nmb->header.opcode == NMB_NAME_REG_OPCODE) ||
844       (nmb->header.opcode == NMB_NAME_RELEASE_OPCODE) ||
845       (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_8) ||
846       (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_9) ||
847       (nmb->header.opcode == NMB_NAME_MULTIHOMED_REG_OPCODE)) &&
848      (nmb->header.arcount == 1)) {
849
850     offset += put_compressed_name_ptr(ubuf,offset,nmb->additional,12);
851
852   } else if (nmb->header.arcount) {
853     offset += put_res_rec((char *)ubuf,offset,nmb->additional,
854                           nmb->header.arcount);  
855   }
856   return(offset);
857 }
858
859
860 /*******************************************************************
861   send a packet_struct
862   ******************************************************************/
863 BOOL send_packet(struct packet_struct *p)
864 {
865   char buf[1024];
866   int len=0;
867
868   bzero(buf,sizeof(buf));
869
870   switch (p->packet_type) 
871     {
872     case NMB_PACKET:
873       len = build_nmb(buf,p);
874       debug_nmb_packet(p);
875       break;
876
877     case DGRAM_PACKET:
878       len = build_dgram(buf,p);
879       break;
880     }
881
882   if (!len) return(False);
883
884   return(send_udp(p->fd,buf,len,p->ip,p->port));
885 }
886
887 /****************************************************************************
888   receive a packet with timeout on a open UDP filedescriptor
889   The timeout is in milliseconds
890   ***************************************************************************/
891 struct packet_struct *receive_packet(int fd,enum packet_type type,int t)
892 {
893   fd_set fds;
894   struct timeval timeout;
895
896   FD_ZERO(&fds);
897   FD_SET(fd,&fds);
898   timeout.tv_sec = t/1000;
899   timeout.tv_usec = 1000*(t%1000);
900
901   sys_select(fd+1,&fds,&timeout);
902
903   if (FD_ISSET(fd,&fds)) 
904     return(read_packet(fd,type));
905
906   return(NULL);
907 }
908
909
910 /****************************************************************************
911 return the number of bits that match between two 4 character buffers
912   ***************************************************************************/
913 static int matching_bits(uchar *p1, uchar *p2)
914 {
915         int i, j, ret = 0;
916         for (i=0; i<4; i++) {
917                 if (p1[i] != p2[i]) break;
918                 ret += 8;
919         }
920
921         if (i==4) return ret;
922
923         for (j=0; j<8; j++) {
924                 if ((p1[i] & (1<<(7-j))) != (p2[i] & (1<<(7-j)))) break;
925                 ret++;
926         }       
927         
928         return ret;
929 }
930
931
932 static uchar sort_ip[4];
933
934 /****************************************************************************
935 compare two query reply records
936   ***************************************************************************/
937 static int name_query_comp(uchar *p1, uchar *p2)
938 {
939         return matching_bits(p2+2, sort_ip) - matching_bits(p1+2, sort_ip);
940 }
941
942 /****************************************************************************
943 sort a set of 6 byte name query response records so that the IPs that
944 have the most leading bits in common with the specified address come first
945   ***************************************************************************/
946 void sort_query_replies(char *data, int n, struct in_addr ip)
947 {
948         if (n <= 1) return;
949
950         putip(sort_ip, (char *)&ip);
951
952         qsort(data, n, 6, QSORT_CAST name_query_comp);
953 }