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