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