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