2 Unix SMB/Netbios implementation.
4 NBT netbios library routines
5 Copyright (C) Andrew Tridgell 1994-1998
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.
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.
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.
25 extern int DEBUGLEVEL;
27 int num_good_sends = 0;
28 int num_good_receives = 0;
30 extern pstring myname;
31 extern struct in_addr ipzero;
33 static struct opcode_names {
34 char *nmb_opcode_name;
36 } nmb_header_opcode_names[] = {
42 {"Refresh(altcode)", 9 },
43 {"Multi-homed Registration", 15 },
47 /****************************************************************************
48 * Lookup a nmb opcode name.
49 ****************************************************************************/
51 char *lookup_opcode_name( int opcode )
53 struct opcode_names *op_namep;
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;
61 return "<unknown opcode>";
64 /****************************************************************************
65 print out a res_rec structure
66 ****************************************************************************/
67 static void debug_nmb_res_rec(struct res_rec *res, char *hdr)
71 DEBUG(4,(" %s: nmb_name=%s rr_type=%d rr_class=%d ttl=%d\n",
73 namestr(&res->rr_name),
78 if (res->rdlength == 0 || res->rdata == NULL) return;
80 for (i = 0; i < res->rdlength; i+= 16)
82 DEBUG(4, (" %s %3x char ", hdr, i));
84 for (j = 0; j < 16; j++)
86 unsigned char x = res->rdata[i+j];
87 if (x < 32 || x > 127) x = '.';
89 if (i+j >= res->rdlength) break;
93 DEBUG(4, (" hex ", i));
95 for (j = 0; j < 16; j++)
97 if (i+j >= res->rdlength) break;
98 DEBUG(4, ("%02X", (unsigned char)res->rdata[i+j]));
105 /****************************************************************************
107 ****************************************************************************/
108 void debug_nmb_packet(struct packet_struct *p)
110 struct nmb_packet *nmb = &p->packet.nmb;
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",
128 nmb->header.arcount));
130 if (nmb->header.qdcount)
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));
138 if (nmb->answers && nmb->header.ancount)
140 debug_nmb_res_rec(nmb->answers,"answers");
142 if (nmb->nsrecs && nmb->header.nscount)
144 debug_nmb_res_rec(nmb->nsrecs,"nsrecs");
146 if (nmb->additional && nmb->header.arcount)
148 debug_nmb_res_rec(nmb->additional,"additional");
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)
160 while ((ubuf[*offset] & 0xC0) == 0xC0) {
161 if (!*got_pointer) (*ret) += 2;
163 (*offset) = ((ubuf[*offset] & ~0xC0)<<8) | ubuf[(*offset)+1];
164 if (loop_count++ == 10 || (*offset) < 0 || (*offset)>(length-2)) {
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)
178 unsigned char *ubuf = (unsigned char *)inbuf;
180 BOOL got_pointer=False;
182 if (length - offset < 2) return(0);
184 /* handle initial name pointers */
185 if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) return(0);
190 if ((m & 0xC0) || offset+m+2 > length) return(0);
192 bzero((char *)name,sizeof(*name));
194 /* the "compressed" part */
195 if (!got_pointer) ret += m + 2;
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;
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;
212 /* remove trailing spaces */
215 while (n && name->name[n]==' ') name->name[n--] = 0;
218 /* now the domain parts (if any) */
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);
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);
228 while (m--) name->scope[n++] = (char)ubuf[offset++];
230 name->scope[n++] = 0;
236 /*******************************************************************
237 put a compressed nmb name into a buffer. return the length of the
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)
250 if (name->name[0] == '*') {
251 /* special case for wildcard name */
254 buf1[15] = name->name_type;
256 sprintf(buf1,"%-15.15s%c",name->name,name->name_type);
264 buf[offset+1+2*m] = 'A' + ((buf1[m]>>4)&0xF);
265 buf[offset+2+2*m] = 'A' + (buf1[m]&0xF);
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);
277 while ((p = strchr(p,'.'))) {
278 buf[offset] = PTR_DIFF(p,&buf[offset]);
279 offset += buf[offset];
282 buf[offset] = strlen(&buf[offset+1]);
288 /*******************************************************************
289 useful for debugging messages
290 ******************************************************************/
291 char *namestr(struct nmb_name *n)
294 static fstring ret[4];
298 sprintf(p,"%s<%02x>",n->name,n->name_type);
300 sprintf(p,"%s<%02x>.%s",n->name,n->name_type,n->scope);
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)
313 *recs = (struct res_rec *)malloc(sizeof(**recs)*count);
314 if (!*recs) return(False);
316 bzero(*recs,sizeof(**recs)*count);
318 for (i=0;i<count;i++) {
319 int l = parse_nmb_name(inbuf,*offset,length,&(*recs)[i].rr_name);
321 if (!l || (*offset)+10 > length) {
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);
330 if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) ||
331 (*offset)+(*recs)[i].rdlength > length) {
335 memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength);
336 (*offset) += (*recs)[i].rdlength;
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)
349 for (i=0;i<count;i++) {
350 int l = put_nmb_name(buf,offset,&recs[i].rr_name);
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;
365 /*******************************************************************
366 parse a dgram packet. Return False if the packet can't be parsed
367 or is invalid for some reason, True otherwise
369 this is documented in section 4.4.1 of RFC1002
370 ******************************************************************/
371 static BOOL parse_dgram(char *inbuf,int length,struct dgram_packet *dgram)
376 bzero((char *)dgram,sizeof(*dgram));
378 if (length < 14) return(False);
380 dgram->header.msg_type = CVAL(inbuf,0);
381 flags = CVAL(inbuf,1);
382 dgram->header.flags.node_type = (enum node_type)((flags>>2)&3);
383 if (flags & 1) dgram->header.flags.more = True;
384 if (flags & 2) dgram->header.flags.first = True;
385 dgram->header.dgm_id = RSVAL(inbuf,2);
386 putip((char *)&dgram->header.source_ip,inbuf+4);
387 dgram->header.source_port = RSVAL(inbuf,8);
388 dgram->header.dgm_length = RSVAL(inbuf,10);
389 dgram->header.packet_offset = RSVAL(inbuf,12);
393 if (dgram->header.msg_type == 0x10 ||
394 dgram->header.msg_type == 0x11 ||
395 dgram->header.msg_type == 0x12) {
396 offset += parse_nmb_name(inbuf,offset,length,&dgram->source_name);
397 offset += parse_nmb_name(inbuf,offset,length,&dgram->dest_name);
400 if (offset >= length || (length-offset > sizeof(dgram->data)))
403 dgram->datasize = length-offset;
404 memcpy(dgram->data,inbuf+offset,dgram->datasize);
410 /*******************************************************************
411 parse a nmb packet. Return False if the packet can't be parsed
412 or is invalid for some reason, True otherwise
413 ******************************************************************/
414 static BOOL parse_nmb(char *inbuf,int length,struct nmb_packet *nmb)
418 bzero((char *)nmb,sizeof(*nmb));
420 if (length < 12) return(False);
422 /* parse the header */
423 nmb->header.name_trn_id = RSVAL(inbuf,0);
425 DEBUG(10,("parse_nmb: packet id = %d\n", nmb->header.name_trn_id));
427 nmb->header.opcode = (CVAL(inbuf,2) >> 3) & 0xF;
428 nmb->header.response = ((CVAL(inbuf,2)>>7)&1)?True:False;
429 nm_flags = ((CVAL(inbuf,2) & 0x7) << 4) + (CVAL(inbuf,3)>>4);
430 nmb->header.nm_flags.bcast = (nm_flags&1)?True:False;
431 nmb->header.nm_flags.recursion_available = (nm_flags&8)?True:False;
432 nmb->header.nm_flags.recursion_desired = (nm_flags&0x10)?True:False;
433 nmb->header.nm_flags.trunc = (nm_flags&0x20)?True:False;
434 nmb->header.nm_flags.authoritative = (nm_flags&0x40)?True:False;
435 nmb->header.rcode = CVAL(inbuf,3) & 0xF;
436 nmb->header.qdcount = RSVAL(inbuf,4);
437 nmb->header.ancount = RSVAL(inbuf,6);
438 nmb->header.nscount = RSVAL(inbuf,8);
439 nmb->header.arcount = RSVAL(inbuf,10);
441 if (nmb->header.qdcount) {
442 offset = parse_nmb_name(inbuf,12,length,&nmb->question.question_name);
443 if (!offset) return(False);
445 if (length - (12+offset) < 4) return(False);
446 nmb->question.question_type = RSVAL(inbuf,12+offset);
447 nmb->question.question_class = RSVAL(inbuf,12+offset+2);
454 /* and any resource records */
455 if (nmb->header.ancount &&
456 !parse_alloc_res_rec(inbuf,&offset,length,&nmb->answers,
457 nmb->header.ancount))
460 if (nmb->header.nscount &&
461 !parse_alloc_res_rec(inbuf,&offset,length,&nmb->nsrecs,
462 nmb->header.nscount))
465 if (nmb->header.arcount &&
466 !parse_alloc_res_rec(inbuf,&offset,length,&nmb->additional,
467 nmb->header.arcount))
473 /*******************************************************************
474 'Copy constructor' for an nmb packet
475 ******************************************************************/
476 static struct packet_struct *copy_nmb_packet(struct packet_struct *packet)
478 struct nmb_packet *nmb;
479 struct nmb_packet *copy_nmb;
480 struct packet_struct *pkt_copy;
482 if(( pkt_copy = (struct packet_struct *)malloc(sizeof(*packet))) == NULL)
484 DEBUG(0,("copy_nmb_packet: malloc fail.\n"));
488 /* Structure copy of entire thing. */
492 /* Ensure this copy is not locked. */
493 pkt_copy->locked = False;
495 /* Ensure this copy has no resource records. */
496 nmb = &packet->packet.nmb;
497 copy_nmb = &pkt_copy->packet.nmb;
499 copy_nmb->answers = NULL;
500 copy_nmb->nsrecs = NULL;
501 copy_nmb->additional = NULL;
503 /* Now copy any resource records. */
507 if((copy_nmb->answers = (struct res_rec *)
508 malloc(nmb->header.ancount * sizeof(struct res_rec))) == NULL)
510 memcpy((char *)copy_nmb->answers, (char *)nmb->answers,
511 nmb->header.ancount * sizeof(struct res_rec));
515 if((copy_nmb->nsrecs = (struct res_rec *)
516 malloc(nmb->header.nscount * sizeof(struct res_rec))) == NULL)
518 memcpy((char *)copy_nmb->nsrecs, (char *)nmb->nsrecs,
519 nmb->header.nscount * sizeof(struct res_rec));
523 if((copy_nmb->additional = (struct res_rec *)
524 malloc(nmb->header.arcount * sizeof(struct res_rec))) == NULL)
526 memcpy((char *)copy_nmb->additional, (char *)nmb->additional,
527 nmb->header.arcount * sizeof(struct res_rec));
534 if(copy_nmb->answers)
535 free((char *)copy_nmb->answers);
537 free((char *)copy_nmb->nsrecs);
538 if(copy_nmb->additional)
539 free((char *)copy_nmb->additional);
540 free((char *)pkt_copy);
542 DEBUG(0,("copy_nmb_packet: malloc fail in resource records.\n"));
546 /*******************************************************************
547 'Copy constructor' for a dgram packet
548 ******************************************************************/
549 static struct packet_struct *copy_dgram_packet(struct packet_struct *packet)
551 struct packet_struct *pkt_copy;
553 if(( pkt_copy = (struct packet_struct *)malloc(sizeof(*packet))) == NULL)
555 DEBUG(0,("copy_dgram_packet: malloc fail.\n"));
559 /* Structure copy of entire thing. */
563 /* Ensure this copy is not locked. */
564 pkt_copy->locked = False;
566 /* There are no additional pointers in a dgram packet,
571 /*******************************************************************
572 'Copy constructor' for a generic packet
573 ******************************************************************/
574 struct packet_struct *copy_packet(struct packet_struct *packet)
576 if(packet->packet_type == NMB_PACKET)
577 return copy_nmb_packet(packet);
578 else if (packet->packet_type == DGRAM_PACKET)
579 return copy_dgram_packet(packet);
583 /*******************************************************************
584 free up any resources associated with an nmb packet
585 ******************************************************************/
586 static void free_nmb_packet(struct nmb_packet *nmb)
588 if (nmb->answers) free(nmb->answers);
589 if (nmb->nsrecs) free(nmb->nsrecs);
590 if (nmb->additional) free(nmb->additional);
593 /*******************************************************************
594 free up any resources associated with a dgram packet
595 ******************************************************************/
596 static void free_dgram_packet(struct dgram_packet *nmb)
598 /* We have nothing to do for a dgram packet. */
601 /*******************************************************************
602 free up any resources associated with a packet
603 ******************************************************************/
604 void free_packet(struct packet_struct *packet)
608 if (packet->packet_type == NMB_PACKET)
609 free_nmb_packet(&packet->packet.nmb);
610 else if (packet->packet_type == DGRAM_PACKET)
611 free_dgram_packet(&packet->packet.dgram);
615 /*******************************************************************
616 read a packet from a socket and parse it, returning a packet ready
617 to be used or put on the queue. This assumes a UDP socket
618 ******************************************************************/
619 struct packet_struct *read_packet(int fd,enum packet_type packet_type)
621 extern struct in_addr lastip;
623 struct packet_struct *packet;
624 char buf[MAX_DGRAM_SIZE];
628 length = read_udp_socket(fd,buf,sizeof(buf));
629 if (length < MIN_DGRAM_SIZE) return(NULL);
631 packet = (struct packet_struct *)malloc(sizeof(*packet));
632 if (!packet) return(NULL);
637 packet->port = lastport;
639 packet->locked = False;
640 packet->timestamp = time(NULL);
641 packet->packet_type = packet_type;
645 ok = parse_nmb(buf,length,&packet->packet.nmb);
649 ok = parse_dgram(buf,length,&packet->packet.dgram);
653 DEBUG(10,("parse_nmb: discarding packet id = %d\n",
654 packet->packet.nmb.header.name_trn_id));
661 DEBUG(5,("%s received a packet of len %d from (%s) port %d\n",
662 timestring(),length,inet_ntoa(packet->ip),packet->port));
668 /*******************************************************************
669 send a udp packet on a already open socket
670 ******************************************************************/
671 static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port)
674 struct sockaddr_in sock_out;
676 /* set the address and port */
677 bzero((char *)&sock_out,sizeof(sock_out));
678 putip((char *)&sock_out.sin_addr,(char *)&ip);
679 sock_out.sin_port = htons( port );
680 sock_out.sin_family = AF_INET;
682 DEBUG(5,("%s sending a packet of len %d to (%s) on port %d\n",
683 timestring(),len,inet_ntoa(ip),port));
685 ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out,
686 sizeof(sock_out)) >= 0);
689 DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n",
690 inet_ntoa(ip),port,strerror(errno)));
698 /*******************************************************************
699 build a dgram packet ready for sending
701 XXXX This currently doesn't handle packets too big for one
702 datagram. It should split them and use the packet_offset, more and
703 first flags to handle the fragmentation. Yuck.
704 ******************************************************************/
705 static int build_dgram(char *buf,struct packet_struct *p)
707 struct dgram_packet *dgram = &p->packet.dgram;
708 unsigned char *ubuf = (unsigned char *)buf;
711 /* put in the header */
712 ubuf[0] = dgram->header.msg_type;
713 ubuf[1] = (((int)dgram->header.flags.node_type)<<2);
714 if (dgram->header.flags.more) ubuf[1] |= 1;
715 if (dgram->header.flags.first) ubuf[1] |= 2;
716 RSSVAL(ubuf,2,dgram->header.dgm_id);
717 putip(ubuf+4,(char *)&dgram->header.source_ip);
718 RSSVAL(ubuf,8,dgram->header.source_port);
719 RSSVAL(ubuf,12,dgram->header.packet_offset);
723 if (dgram->header.msg_type == 0x10 ||
724 dgram->header.msg_type == 0x11 ||
725 dgram->header.msg_type == 0x12) {
726 offset += put_nmb_name((char *)ubuf,offset,&dgram->source_name);
727 offset += put_nmb_name((char *)ubuf,offset,&dgram->dest_name);
730 memcpy(ubuf+offset,dgram->data,dgram->datasize);
731 offset += dgram->datasize;
733 /* automatically set the dgm_length */
734 dgram->header.dgm_length = offset;
735 RSSVAL(ubuf,10,dgram->header.dgm_length);
740 /*******************************************************************
742 ******************************************************************/
743 void make_nmb_name(struct nmb_name *n,char *name,int type,char *this_scope)
745 StrnCpy(n->name,name,15);
747 n->name_type = (unsigned int)type & 0xFF;
748 StrnCpy(n->scope,this_scope,63);
751 /*******************************************************************
752 Compare two nmb names
753 ******************************************************************/
755 BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2)
757 return ((n1->name_type == n2->name_type) &&
758 strequal(n1->name ,n2->name ) &&
759 strequal(n1->scope,n2->scope));
762 /*******************************************************************
763 build a nmb packet ready for sending
765 XXXX this currently relies on not being passed something that expands
766 to a packet too big for the buffer. Eventually this should be
767 changed to set the trunc bit so the receiver can request the rest
768 via tcp (when that becomes supported)
769 ******************************************************************/
770 static int build_nmb(char *buf,struct packet_struct *p)
772 struct nmb_packet *nmb = &p->packet.nmb;
773 unsigned char *ubuf = (unsigned char *)buf;
776 /* put in the header */
777 RSSVAL(ubuf,offset,nmb->header.name_trn_id);
778 ubuf[offset+2] = (nmb->header.opcode & 0xF) << 3;
779 if (nmb->header.response) ubuf[offset+2] |= (1<<7);
780 if (nmb->header.nm_flags.authoritative &&
781 nmb->header.response) ubuf[offset+2] |= 0x4;
782 if (nmb->header.nm_flags.trunc) ubuf[offset+2] |= 0x2;
783 if (nmb->header.nm_flags.recursion_desired) ubuf[offset+2] |= 0x1;
784 if (nmb->header.nm_flags.recursion_available &&
785 nmb->header.response) ubuf[offset+3] |= 0x80;
786 if (nmb->header.nm_flags.bcast) ubuf[offset+3] |= 0x10;
787 ubuf[offset+3] |= (nmb->header.rcode & 0xF);
789 RSSVAL(ubuf,offset+4,nmb->header.qdcount);
790 RSSVAL(ubuf,offset+6,nmb->header.ancount);
791 RSSVAL(ubuf,offset+8,nmb->header.nscount);
792 RSSVAL(ubuf,offset+10,nmb->header.arcount);
795 if (nmb->header.qdcount) {
796 /* XXXX this doesn't handle a qdcount of > 1 */
797 offset += put_nmb_name((char *)ubuf,offset,&nmb->question.question_name);
798 RSSVAL(ubuf,offset,nmb->question.question_type);
799 RSSVAL(ubuf,offset+2,nmb->question.question_class);
803 if (nmb->header.ancount)
804 offset += put_res_rec((char *)ubuf,offset,nmb->answers,
805 nmb->header.ancount);
807 if (nmb->header.nscount)
808 offset += put_res_rec((char *)ubuf,offset,nmb->nsrecs,
809 nmb->header.nscount);
811 if (nmb->header.arcount)
812 offset += put_res_rec((char *)ubuf,offset,nmb->additional,
813 nmb->header.arcount);
819 /*******************************************************************
821 ******************************************************************/
822 BOOL send_packet(struct packet_struct *p)
827 bzero(buf,sizeof(buf));
829 switch (p->packet_type)
832 len = build_nmb(buf,p);
837 len = build_dgram(buf,p);
841 if (!len) return(False);
843 return(send_udp(p->fd,buf,len,p->ip,p->port));
846 /****************************************************************************
847 receive a packet with timeout on a open UDP filedescriptor
848 The timeout is in milliseconds
849 ***************************************************************************/
850 struct packet_struct *receive_packet(int fd,enum packet_type type,int t)
853 struct timeval timeout;
857 timeout.tv_sec = t/1000;
858 timeout.tv_usec = 1000*(t%1000);
860 sys_select(&fds,&timeout);
862 if (FD_ISSET(fd,&fds))
863 return(read_packet(fd,type));