backout all the changes to nmbd.
[kai/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-1995
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
34 /****************************************************************************
35   print out a res_rec structure
36   ****************************************************************************/
37 static void debug_nmb_res_rec(struct res_rec *res, char *hdr)
38 {
39   int i, j;
40
41   DEBUG(4,("    %s: nmb_name=%s rr_type=%d rr_class=%d ttl=%d\n",
42            hdr,
43            namestr(&res->rr_name),
44            res->rr_type,
45            res->rr_class,
46            res->ttl));
47                 
48   if (res->rdlength == 0 || res->rdata == NULL) return;
49
50   for (i = 0; i < res->rdlength; i+= 16)
51     {
52       DEBUG(4, ("    %s %3x char ", hdr, i));
53
54       for (j = 0; j < 16; j++)
55         {
56           unsigned char x = res->rdata[i+j];
57           if (x < 32 || x > 127) x = '.';
58           
59           if (i+j >= res->rdlength) break;
60           DEBUG(4, ("%c", x));
61         }
62       
63       DEBUG(4, ("   hex ", i));
64
65       for (j = 0; j < 16; j++)
66         {
67           if (i+j >= res->rdlength) break;
68           DEBUG(4, ("%02X", (unsigned char)res->rdata[i+j]));
69         }
70       
71       DEBUG(4, ("\n"));
72     }
73 }
74
75 /****************************************************************************
76   process a nmb packet
77   ****************************************************************************/
78 void debug_nmb_packet(struct packet_struct *p)
79 {
80   struct nmb_packet *nmb = &p->packet.nmb;
81   
82   DEBUG(4,("nmb packet from %s header: id=%d opcode=%d response=%s\n",
83            inet_ntoa(p->ip),
84            nmb->header.name_trn_id,nmb->header.opcode,BOOLSTR(nmb->header.response)));
85   DEBUG(4,("    header: flags: bcast=%s rec_avail=%s rec_des=%s trunc=%s auth=%s\n",
86            BOOLSTR(nmb->header.nm_flags.bcast),
87            BOOLSTR(nmb->header.nm_flags.recursion_available),
88            BOOLSTR(nmb->header.nm_flags.recursion_desired),
89            BOOLSTR(nmb->header.nm_flags.trunc),
90            BOOLSTR(nmb->header.nm_flags.authoritative)));
91   DEBUG(4,("    header: rcode=%d qdcount=%d ancount=%d nscount=%d arcount=%d\n",
92            nmb->header.rcode,
93            nmb->header.qdcount,
94            nmb->header.ancount,
95            nmb->header.nscount,
96            nmb->header.arcount));
97
98   if (nmb->header.qdcount)
99     {
100       DEBUG(4,("    question: q_name=%s q_type=%d q_class=%d\n",
101                namestr(&nmb->question.question_name),
102                nmb->question.question_type,
103                nmb->question.question_class));
104     }
105
106   if (nmb->answers && nmb->header.ancount) 
107     {
108       debug_nmb_res_rec(nmb->answers,"answers");
109     }
110   if (nmb->nsrecs && nmb->header.nscount)
111     {
112       debug_nmb_res_rec(nmb->nsrecs,"nsrecs");
113     }
114   if (nmb->additional && nmb->header.arcount)
115     {
116       debug_nmb_res_rec(nmb->additional,"additional");
117     }
118 }
119
120 /*******************************************************************
121   handle "compressed" name pointers
122   ******************************************************************/
123 static BOOL handle_name_ptrs(unsigned char *ubuf,int *offset,int length,
124                              BOOL *got_pointer,int *ret)
125 {
126   int loop_count=0;
127   
128   while ((ubuf[*offset] & 0xC0) == 0xC0) {
129     if (!*got_pointer) (*ret) += 2;
130     (*got_pointer)=True;
131     (*offset) = ((ubuf[*offset] & ~0xC0)<<8) | ubuf[(*offset)+1];
132     if (loop_count++ == 10 || (*offset) < 0 || (*offset)>(length-2)) {
133       return(False);
134     }
135   }
136   return(True);
137 }
138
139 /*******************************************************************
140   parse a nmb name from "compressed" format to something readable
141   return the space taken by the name, or 0 if the name is invalid
142   ******************************************************************/
143 static int parse_nmb_name(char *inbuf,int offset,int length, struct nmb_name *name)
144 {
145   int m,n=0;
146   unsigned char *ubuf = (unsigned char *)inbuf;
147   int ret = 0;
148   BOOL got_pointer=False;
149
150   if (length - offset < 2) return(0);  
151
152   /* handle initial name pointers */
153   if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) return(0);
154   
155   m = ubuf[offset];
156
157   if (!m) return(0);
158   if ((m & 0xC0) || offset+m+2 > length) return(0);
159
160   bzero((char *)name,sizeof(*name));
161
162   /* the "compressed" part */
163   if (!got_pointer) ret += m + 2;
164   offset++;
165   while (m) {
166     unsigned char c1,c2;
167     c1 = ubuf[offset++]-'A';
168     c2 = ubuf[offset++]-'A';
169     if ((c1 & 0xF0) || (c2 & 0xF0)) return(0);
170     name->name[n++] = (c1<<4) | c2;
171     m -= 2;
172   }
173   name->name[n] = 0;
174
175   if (n==16) {
176     /* parse out the name type, 
177        its always in the 16th byte of the name */
178     name->name_type = name->name[15];
179   
180     /* remove trailing spaces */
181     name->name[15] = 0;
182     n = 14;
183     while (n && name->name[n]==' ') name->name[n--] = 0;  
184   }
185
186   /* now the domain parts (if any) */
187   n = 0;
188   while ((m=ubuf[offset])) {
189     /* we can have pointers within the domain part as well */
190     if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) return(0);
191
192     if (!got_pointer) ret += m+1;
193     if (n) name->scope[n++] = '.';
194     if (m+2+offset>length || n+m+1>sizeof(name->scope)) return(0);
195     offset++;
196     while (m--) name->scope[n++] = (char)ubuf[offset++];
197   }
198   name->scope[n++] = 0;  
199
200   return(ret);
201 }
202
203
204 /*******************************************************************
205   put a compressed nmb name into a buffer. return the length of the
206   compressed name
207
208   compressed names are really weird. The "compression" doubles the
209   size. The idea is that it also means that compressed names conform
210   to the doman name system. See RFC1002.
211   ******************************************************************/
212 static int put_nmb_name(char *buf,int offset,struct nmb_name *name)
213 {
214   int ret,m;
215   fstring buf1;
216   char *p;
217
218   if (name->name[0] == '*') {
219     /* special case for wildcard name */
220     bzero(buf1,20);
221     buf1[0] = '*';
222   } else {
223     sprintf(buf1,"%-15.15s%c",name->name,name->name_type);
224   }
225
226   buf[offset] = 0x20;
227
228   ret = 34;
229
230   for (m=0;m<16;m++) {
231     buf[offset+1+2*m] = 'A' + ((buf1[m]>>4)&0xF);
232     buf[offset+2+2*m] = 'A' + (buf1[m]&0xF);
233   }
234   offset += 33;
235
236   buf[offset] = 0;
237
238   if (name->scope[0]) {
239     /* XXXX this scope handling needs testing */
240     ret += strlen(name->scope) + 1;
241     strcpy(&buf[offset+1],name->scope);  
242   
243     p = &buf[offset+1];
244     while ((p = strchr(p,'.'))) {
245       buf[offset] = PTR_DIFF(p,&buf[offset]);
246       offset += buf[offset];
247       p = &buf[offset+1];
248     }
249     buf[offset] = strlen(&buf[offset+1]);
250   }
251
252   return(ret);
253 }
254
255 /*******************************************************************
256   useful for debugging messages
257   ******************************************************************/
258 char *namestr(struct nmb_name *n)
259 {
260   static int i=0;
261   static fstring ret[4];
262   char *p = ret[i];
263
264   if (!n->scope[0])
265     sprintf(p,"%s(%x)",n->name,n->name_type);
266   else
267     sprintf(p,"%s(%x).%s",n->name,n->name_type,n->scope);
268
269   i = (i+1)%4;
270   return(p);
271 }
272
273 /*******************************************************************
274   allocate and parse some resource records
275   ******************************************************************/
276 static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length,
277                                 struct res_rec **recs, int count)
278 {
279   int i;
280   *recs = (struct res_rec *)malloc(sizeof(**recs)*count);
281   if (!*recs) return(False);
282
283   bzero(*recs,sizeof(**recs)*count);
284
285   for (i=0;i<count;i++) {
286     int l = parse_nmb_name(inbuf,*offset,length,&(*recs)[i].rr_name);
287     (*offset) += l;
288     if (!l || (*offset)+10 > length) {
289       free(*recs);
290       return(False);
291     }
292     (*recs)[i].rr_type = RSVAL(inbuf,(*offset));
293     (*recs)[i].rr_class = RSVAL(inbuf,(*offset)+2);
294     (*recs)[i].ttl = RIVAL(inbuf,(*offset)+4);
295     (*recs)[i].rdlength = RSVAL(inbuf,(*offset)+8);
296     (*offset) += 10;
297     if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) || 
298         (*offset)+(*recs)[i].rdlength > length) {
299       free(*recs);
300       return(False);
301     }
302     memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength);
303     (*offset) += (*recs)[i].rdlength;    
304   }
305   return(True);
306 }
307
308 /*******************************************************************
309   put a resource record into a packet
310   ******************************************************************/
311 static int put_res_rec(char *buf,int offset,struct res_rec *recs,int count)
312 {
313   int ret=0;
314   int i;
315
316   for (i=0;i<count;i++) {
317     int l = put_nmb_name(buf,offset,&recs[i].rr_name);
318     offset += l;
319     ret += l;
320     RSSVAL(buf,offset,recs[i].rr_type);
321     RSSVAL(buf,offset+2,recs[i].rr_class);
322     RSIVAL(buf,offset+4,recs[i].ttl);
323     RSSVAL(buf,offset+8,recs[i].rdlength);
324     memcpy(buf+offset+10,recs[i].rdata,recs[i].rdlength);
325     offset += 10+recs[i].rdlength;
326     ret += 10+recs[i].rdlength;
327   }
328
329   return(ret);
330 }
331
332 /*******************************************************************
333   parse a dgram packet. Return False if the packet can't be parsed 
334   or is invalid for some reason, True otherwise 
335
336   this is documented in section 4.4.1 of RFC1002
337   ******************************************************************/
338 static BOOL parse_dgram(char *inbuf,int length,struct dgram_packet *dgram)
339 {
340   int offset;
341   int flags;
342
343   bzero((char *)dgram,sizeof(*dgram));
344
345   if (length < 14) return(False);
346
347   dgram->header.msg_type = CVAL(inbuf,0);
348   flags = CVAL(inbuf,1);
349   dgram->header.flags.node_type = (enum node_type)((flags>>2)&3);
350   if (flags & 1) dgram->header.flags.more = True;
351   if (flags & 2) dgram->header.flags.first = True;
352   dgram->header.dgm_id = RSVAL(inbuf,2);
353   putip((char *)&dgram->header.source_ip,inbuf+4);
354   dgram->header.source_port = RSVAL(inbuf,8);
355   dgram->header.dgm_length = RSVAL(inbuf,10);
356   dgram->header.packet_offset = RSVAL(inbuf,12);
357
358   offset = 14;
359
360   if (dgram->header.msg_type == 0x10 ||
361       dgram->header.msg_type == 0x11 ||
362       dgram->header.msg_type == 0x12) {      
363     offset += parse_nmb_name(inbuf,offset,length,&dgram->source_name);
364     offset += parse_nmb_name(inbuf,offset,length,&dgram->dest_name);
365   }
366
367   if (offset >= length || (length-offset > sizeof(dgram->data))) 
368     return(False);
369
370   dgram->datasize = length-offset;
371   memcpy(dgram->data,inbuf+offset,dgram->datasize);
372
373   return(True);
374 }
375
376
377 /*******************************************************************
378   parse a nmb packet. Return False if the packet can't be parsed 
379   or is invalid for some reason, True otherwise 
380   ******************************************************************/
381 static BOOL parse_nmb(char *inbuf,int length,struct nmb_packet *nmb)
382 {
383   int nm_flags,offset;
384
385   bzero((char *)nmb,sizeof(*nmb));
386
387   if (length < 12) return(False);
388
389   /* parse the header */
390   nmb->header.name_trn_id = RSVAL(inbuf,0);
391   nmb->header.opcode = (CVAL(inbuf,2) >> 3) & 0xF;
392   nmb->header.response = ((CVAL(inbuf,2)>>7)&1)?True:False;
393   nm_flags = ((CVAL(inbuf,2) & 0x7) << 4) + (CVAL(inbuf,3)>>4);
394   nmb->header.nm_flags.bcast = (nm_flags&1)?True:False;
395   nmb->header.nm_flags.recursion_available = (nm_flags&8)?True:False;
396   nmb->header.nm_flags.recursion_desired = (nm_flags&0x10)?True:False;
397   nmb->header.nm_flags.trunc = (nm_flags&0x20)?True:False;
398   nmb->header.nm_flags.authoritative = (nm_flags&0x40)?True:False;
399   nmb->header.rcode = CVAL(inbuf,3) & 0xF;
400   nmb->header.qdcount = RSVAL(inbuf,4);
401   nmb->header.ancount = RSVAL(inbuf,6);
402   nmb->header.nscount = RSVAL(inbuf,8);
403   nmb->header.arcount = RSVAL(inbuf,10);
404   
405   if (nmb->header.qdcount) {
406     offset = parse_nmb_name(inbuf,12,length,&nmb->question.question_name);
407     if (!offset) return(False);
408
409     if (length - (12+offset) < 4) return(False);
410     nmb->question.question_type = RSVAL(inbuf,12+offset);
411     nmb->question.question_class = RSVAL(inbuf,12+offset+2);
412
413     offset += 12+4;
414   } else {
415     offset = 12;
416   }
417
418   /* and any resource records */
419   if (nmb->header.ancount && 
420       !parse_alloc_res_rec(inbuf,&offset,length,&nmb->answers,
421                            nmb->header.ancount))
422     return(False);
423
424   if (nmb->header.nscount && 
425       !parse_alloc_res_rec(inbuf,&offset,length,&nmb->nsrecs,
426                            nmb->header.nscount))
427     return(False);
428   
429   if (nmb->header.arcount && 
430       !parse_alloc_res_rec(inbuf,&offset,length,&nmb->additional,
431                            nmb->header.arcount))
432     return(False);
433
434   return(True);
435 }
436
437 /*******************************************************************
438   free up any resources associated with an nmb packet
439   ******************************************************************/
440 void free_nmb_packet(struct nmb_packet *nmb)
441 {  
442   if (nmb->answers) free(nmb->answers);
443   if (nmb->nsrecs) free(nmb->nsrecs);
444   if (nmb->additional) free(nmb->additional);
445 }
446
447 /*******************************************************************
448   free up any resources associated with a packet
449   ******************************************************************/
450 void free_packet(struct packet_struct *packet)
451 {  
452   if (packet->packet_type == NMB_PACKET)
453     free_nmb_packet(&packet->packet.nmb);
454   free(packet);
455 }
456
457 /*******************************************************************
458   read a packet from a socket and parse it, returning a packet ready
459   to be used or put on the queue. This assumes a UDP socket
460   ******************************************************************/
461 struct packet_struct *read_packet(int fd,enum packet_type packet_type)
462 {
463   extern struct in_addr lastip;
464   extern int lastport;
465   struct packet_struct *packet;
466   char buf[MAX_DGRAM_SIZE];
467   int length;
468   BOOL ok=False;
469   
470   length = read_udp_socket(fd,buf,sizeof(buf));
471   if (length < MIN_DGRAM_SIZE) return(NULL);
472
473   packet = (struct packet_struct *)malloc(sizeof(*packet));
474   if (!packet) return(NULL);
475
476   packet->next = NULL;
477   packet->prev = NULL;
478   packet->ip = lastip;
479   packet->port = lastport;
480   packet->fd = fd;
481   packet->timestamp = time(NULL);
482   packet->packet_type = packet_type;
483   switch (packet_type) 
484     {
485     case NMB_PACKET:
486       ok = parse_nmb(buf,length,&packet->packet.nmb);
487       break;
488
489     case DGRAM_PACKET:
490       ok = parse_dgram(buf,length,&packet->packet.dgram);
491       break;
492     }
493   if (!ok) {
494     free(packet);
495     return(NULL);
496   }
497
498   num_good_receives++;
499
500   DEBUG(5,("%s received a packet of len %d from (%s) port %d\n",
501            timestring(),length,inet_ntoa(packet->ip),packet->port));
502
503   return(packet);
504 }
505                                          
506
507 /*******************************************************************
508   send a udp packet on a already open socket
509   ******************************************************************/
510 static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port)
511 {
512   BOOL ret;
513   struct sockaddr_in sock_out;
514
515   /* set the address and port */
516   bzero((char *)&sock_out,sizeof(sock_out));
517   putip((char *)&sock_out.sin_addr,(char *)&ip);
518   sock_out.sin_port = htons( port );
519   sock_out.sin_family = AF_INET;
520   
521   DEBUG(5,("%s sending a packet of len %d to (%s) on port %d\n",
522            timestring(),len,inet_ntoa(ip),port));
523         
524   ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out,
525                 sizeof(sock_out)) >= 0);
526
527   if (!ret)
528     DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n",
529              inet_ntoa(ip),port,strerror(errno)));
530
531   if (ret)
532     num_good_sends++;
533
534   return(ret);
535 }
536
537 /*******************************************************************
538   build a dgram packet ready for sending
539
540   XXXX This currently doesn't handle packets too big for one
541   datagram. It should split them and use the packet_offset, more and
542   first flags to handle the fragmentation. Yuck.
543   ******************************************************************/
544 static int build_dgram(char *buf,struct packet_struct *p)
545 {
546   struct dgram_packet *dgram = &p->packet.dgram;
547   unsigned char *ubuf = (unsigned char *)buf;
548   int offset=0;
549
550   /* put in the header */
551   ubuf[0] = dgram->header.msg_type;
552   ubuf[1] = (((int)dgram->header.flags.node_type)<<2);
553   if (dgram->header.flags.more) ubuf[1] |= 1;
554   if (dgram->header.flags.first) ubuf[1] |= 2;
555   RSSVAL(ubuf,2,dgram->header.dgm_id);
556   putip(ubuf+4,(char *)&dgram->header.source_ip);
557   RSSVAL(ubuf,8,dgram->header.source_port);
558   RSSVAL(ubuf,12,dgram->header.packet_offset);
559
560   offset = 14;
561
562   if (dgram->header.msg_type == 0x10 ||
563       dgram->header.msg_type == 0x11 ||
564       dgram->header.msg_type == 0x12) {      
565     offset += put_nmb_name((char *)ubuf,offset,&dgram->source_name);
566     offset += put_nmb_name((char *)ubuf,offset,&dgram->dest_name);
567   }
568
569   memcpy(ubuf+offset,dgram->data,dgram->datasize);
570   offset += dgram->datasize;
571
572   /* automatically set the dgm_length */
573   dgram->header.dgm_length = offset;
574   RSSVAL(ubuf,10,dgram->header.dgm_length); 
575
576   return(offset);
577 }
578
579 /*******************************************************************
580   build a nmb name
581   ******************************************************************/
582 void make_nmb_name(struct nmb_name *n,char *name,int type,char *this_scope)
583 {
584   strcpy(n->name,name);
585   strupper(n->name);
586   n->name_type = type;
587   strcpy(n->scope,this_scope);
588 }
589
590
591 /*******************************************************************
592   build a nmb packet ready for sending
593
594   XXXX this currently relies on not being passed something that expands
595   to a packet too big for the buffer. Eventually this should be
596   changed to set the trunc bit so the receiver can request the rest
597   via tcp (when that becomes supported)
598   ******************************************************************/
599 static int build_nmb(char *buf,struct packet_struct *p)
600 {
601   struct nmb_packet *nmb = &p->packet.nmb;
602   unsigned char *ubuf = (unsigned char *)buf;
603   int offset=0;
604
605   /* put in the header */
606   RSSVAL(ubuf,offset,nmb->header.name_trn_id);
607   ubuf[offset+2] = (nmb->header.opcode & 0xF) << 3;
608   if (nmb->header.response) ubuf[offset+2] |= (1<<7);
609   if (nmb->header.nm_flags.authoritative) ubuf[offset+2] |= 0x4;
610   if (nmb->header.nm_flags.trunc) ubuf[offset+2] |= 0x2;
611   if (nmb->header.nm_flags.recursion_desired) ubuf[offset+2] |= 0x1;
612   if (nmb->header.nm_flags.recursion_available &&
613       nmb->header.response) ubuf[offset+3] |= 0x80;
614   if (nmb->header.nm_flags.bcast) ubuf[offset+3] |= 0x10;
615   ubuf[offset+3] |= (nmb->header.rcode & 0xF);
616
617   RSSVAL(ubuf,offset+4,nmb->header.qdcount);
618   RSSVAL(ubuf,offset+6,nmb->header.ancount);
619   RSSVAL(ubuf,offset+8,nmb->header.nscount);
620   RSSVAL(ubuf,offset+10,nmb->header.arcount);
621   
622   offset += 12;
623   if (nmb->header.qdcount) {
624     /* XXXX this doesn't handle a qdcount of > 1 */
625     offset += put_nmb_name((char *)ubuf,offset,&nmb->question.question_name);
626     RSSVAL(ubuf,offset,nmb->question.question_type);
627     RSSVAL(ubuf,offset+2,nmb->question.question_class);
628     offset += 4;
629   }
630
631   if (nmb->header.ancount)
632     offset += put_res_rec((char *)ubuf,offset,nmb->answers,
633                           nmb->header.ancount);
634
635   if (nmb->header.nscount)
636     offset += put_res_rec((char *)ubuf,offset,nmb->nsrecs,
637                           nmb->header.nscount);
638
639   if (nmb->header.arcount)
640     offset += put_res_rec((char *)ubuf,offset,nmb->additional,
641                           nmb->header.arcount);  
642
643   return(offset);
644 }
645
646
647 /*******************************************************************
648   send a packet_struct
649   ******************************************************************/
650 BOOL send_packet(struct packet_struct *p)
651 {
652   char buf[1024];
653   int len=0;
654
655   bzero(buf,sizeof(buf));
656
657   switch (p->packet_type) 
658     {
659     case NMB_PACKET:
660       len = build_nmb(buf,p);
661       break;
662
663     case DGRAM_PACKET:
664       len = build_dgram(buf,p);
665       break;
666     }
667
668   if (!len) return(False);
669
670   return(send_udp(p->fd,buf,len,p->ip,p->port));
671 }
672
673 /****************************************************************************
674   receive a packet with timeout on a open UDP filedescriptor
675   The timeout is in milliseconds
676   ***************************************************************************/
677 struct packet_struct *receive_packet(int fd,enum packet_type type,int t)
678 {
679   fd_set fds;
680   struct timeval timeout;
681
682   FD_ZERO(&fds);
683   FD_SET(fd,&fds);
684   timeout.tv_sec = t/1000;
685   timeout.tv_usec = 1000*(t%1000);
686
687   sys_select(&fds,&timeout);
688
689   if (FD_ISSET(fd,&fds)) 
690     return(read_packet(fd,type));
691
692   return(NULL);
693 }
694
695