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