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 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)
371 buf[offset] = (0xC0 | ((ptr_offset >> 8) & 0xFF));
372 buf[offset+1] = (ptr_offset & 0xFF);
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;
386 /*******************************************************************
387 parse a dgram packet. Return False if the packet can't be parsed
388 or is invalid for some reason, True otherwise
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)
397 bzero((char *)dgram,sizeof(*dgram));
399 if (length < 14) return(False);
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);
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);
421 if (offset >= length || (length-offset > sizeof(dgram->data)))
424 dgram->datasize = length-offset;
425 memcpy(dgram->data,inbuf+offset,dgram->datasize);
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)
439 bzero((char *)nmb,sizeof(*nmb));
441 if (length < 12) return(False);
443 /* parse the header */
444 nmb->header.name_trn_id = RSVAL(inbuf,0);
446 DEBUG(10,("parse_nmb: packet id = %d\n", nmb->header.name_trn_id));
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);
462 if (nmb->header.qdcount) {
463 offset = parse_nmb_name(inbuf,12,length,&nmb->question.question_name);
464 if (!offset) return(False);
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);
475 /* and any resource records */
476 if (nmb->header.ancount &&
477 !parse_alloc_res_rec(inbuf,&offset,length,&nmb->answers,
478 nmb->header.ancount))
481 if (nmb->header.nscount &&
482 !parse_alloc_res_rec(inbuf,&offset,length,&nmb->nsrecs,
483 nmb->header.nscount))
486 if (nmb->header.arcount &&
487 !parse_alloc_res_rec(inbuf,&offset,length,&nmb->additional,
488 nmb->header.arcount))
494 /*******************************************************************
495 'Copy constructor' for an nmb packet
496 ******************************************************************/
497 static struct packet_struct *copy_nmb_packet(struct packet_struct *packet)
499 struct nmb_packet *nmb;
500 struct nmb_packet *copy_nmb;
501 struct packet_struct *pkt_copy;
503 if(( pkt_copy = (struct packet_struct *)malloc(sizeof(*packet))) == NULL)
505 DEBUG(0,("copy_nmb_packet: malloc fail.\n"));
509 /* Structure copy of entire thing. */
513 /* Ensure this copy is not locked. */
514 pkt_copy->locked = False;
516 /* Ensure this copy has no resource records. */
517 nmb = &packet->packet.nmb;
518 copy_nmb = &pkt_copy->packet.nmb;
520 copy_nmb->answers = NULL;
521 copy_nmb->nsrecs = NULL;
522 copy_nmb->additional = NULL;
524 /* Now copy any resource records. */
528 if((copy_nmb->answers = (struct res_rec *)
529 malloc(nmb->header.ancount * sizeof(struct res_rec))) == NULL)
531 memcpy((char *)copy_nmb->answers, (char *)nmb->answers,
532 nmb->header.ancount * sizeof(struct res_rec));
536 if((copy_nmb->nsrecs = (struct res_rec *)
537 malloc(nmb->header.nscount * sizeof(struct res_rec))) == NULL)
539 memcpy((char *)copy_nmb->nsrecs, (char *)nmb->nsrecs,
540 nmb->header.nscount * sizeof(struct res_rec));
544 if((copy_nmb->additional = (struct res_rec *)
545 malloc(nmb->header.arcount * sizeof(struct res_rec))) == NULL)
547 memcpy((char *)copy_nmb->additional, (char *)nmb->additional,
548 nmb->header.arcount * sizeof(struct res_rec));
555 if(copy_nmb->answers)
556 free((char *)copy_nmb->answers);
558 free((char *)copy_nmb->nsrecs);
559 if(copy_nmb->additional)
560 free((char *)copy_nmb->additional);
561 free((char *)pkt_copy);
563 DEBUG(0,("copy_nmb_packet: malloc fail in resource records.\n"));
567 /*******************************************************************
568 'Copy constructor' for a dgram packet
569 ******************************************************************/
570 static struct packet_struct *copy_dgram_packet(struct packet_struct *packet)
572 struct packet_struct *pkt_copy;
574 if(( pkt_copy = (struct packet_struct *)malloc(sizeof(*packet))) == NULL)
576 DEBUG(0,("copy_dgram_packet: malloc fail.\n"));
580 /* Structure copy of entire thing. */
584 /* Ensure this copy is not locked. */
585 pkt_copy->locked = False;
587 /* There are no additional pointers in a dgram packet,
592 /*******************************************************************
593 'Copy constructor' for a generic packet
594 ******************************************************************/
595 struct packet_struct *copy_packet(struct packet_struct *packet)
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);
604 /*******************************************************************
605 free up any resources associated with an nmb packet
606 ******************************************************************/
607 static void free_nmb_packet(struct nmb_packet *nmb)
609 if (nmb->answers) free(nmb->answers);
610 if (nmb->nsrecs) free(nmb->nsrecs);
611 if (nmb->additional) free(nmb->additional);
614 /*******************************************************************
615 free up any resources associated with a dgram packet
616 ******************************************************************/
617 static void free_dgram_packet(struct dgram_packet *nmb)
619 /* We have nothing to do for a dgram packet. */
622 /*******************************************************************
623 free up any resources associated with a packet
624 ******************************************************************/
625 void free_packet(struct packet_struct *packet)
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);
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)
642 extern struct in_addr lastip;
644 struct packet_struct *packet;
645 char buf[MAX_DGRAM_SIZE];
649 length = read_udp_socket(fd,buf,sizeof(buf));
650 if (length < MIN_DGRAM_SIZE) return(NULL);
652 packet = (struct packet_struct *)malloc(sizeof(*packet));
653 if (!packet) return(NULL);
658 packet->port = lastport;
660 packet->locked = False;
661 packet->timestamp = time(NULL);
662 packet->packet_type = packet_type;
666 ok = parse_nmb(buf,length,&packet->packet.nmb);
670 ok = parse_dgram(buf,length,&packet->packet.dgram);
674 DEBUG(10,("parse_nmb: discarding packet id = %d\n",
675 packet->packet.nmb.header.name_trn_id));
682 DEBUG(5,("%s received a packet of len %d from (%s) port %d\n",
683 timestring(),length,inet_ntoa(packet->ip),packet->port));
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)
695 struct sockaddr_in sock_out;
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;
703 DEBUG(5,("%s sending a packet of len %d to (%s) on port %d\n",
704 timestring(),len,inet_ntoa(ip),port));
706 ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out,
707 sizeof(sock_out)) >= 0);
710 DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n",
711 inet_ntoa(ip),port,strerror(errno)));
719 /*******************************************************************
720 build a dgram packet ready for sending
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)
728 struct dgram_packet *dgram = &p->packet.dgram;
729 unsigned char *ubuf = (unsigned char *)buf;
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);
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);
751 memcpy(ubuf+offset,dgram->data,dgram->datasize);
752 offset += dgram->datasize;
754 /* automatically set the dgm_length */
755 dgram->header.dgm_length = offset;
756 RSSVAL(ubuf,10,dgram->header.dgm_length);
761 /*******************************************************************
763 ******************************************************************/
764 void make_nmb_name(struct nmb_name *n,char *name,int type,char *this_scope)
766 StrnCpy(n->name,name,15);
768 n->name_type = (unsigned int)type & 0xFF;
769 StrnCpy(n->scope,this_scope,63);
772 /*******************************************************************
773 Compare two nmb names
774 ******************************************************************/
776 BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2)
778 return ((n1->name_type == n2->name_type) &&
779 strequal(n1->name ,n2->name ) &&
780 strequal(n1->scope,n2->scope));
783 /*******************************************************************
784 build a nmb packet ready for sending
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)
793 struct nmb_packet *nmb = &p->packet.nmb;
794 unsigned char *ubuf = (unsigned char *)buf;
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);
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);
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);
824 if (nmb->header.ancount)
825 offset += put_res_rec((char *)ubuf,offset,nmb->answers,
826 nmb->header.ancount);
828 if (nmb->header.nscount)
829 offset += put_res_rec((char *)ubuf,offset,nmb->nsrecs,
830 nmb->header.nscount);
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.
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)) {
847 offset += put_compressed_name_ptr(ubuf,offset,nmb->additional,12);
849 } else if (nmb->header.arcount) {
850 offset += put_res_rec((char *)ubuf,offset,nmb->additional,
851 nmb->header.arcount);
857 /*******************************************************************
859 ******************************************************************/
860 BOOL send_packet(struct packet_struct *p)
865 bzero(buf,sizeof(buf));
867 switch (p->packet_type)
870 len = build_nmb(buf,p);
875 len = build_dgram(buf,p);
879 if (!len) return(False);
881 return(send_udp(p->fd,buf,len,p->ip,p->port));
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)
891 struct timeval timeout;
895 timeout.tv_sec = t/1000;
896 timeout.tv_usec = 1000*(t%1000);
898 sys_select(&fds,&timeout);
900 if (FD_ISSET(fd,&fds))
901 return(read_packet(fd,type));