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 static struct opcode_names {
31 char *nmb_opcode_name;
33 } nmb_header_opcode_names[] = {
39 {"Refresh(altcode)", 9 },
40 {"Multi-homed Registration", 15 },
44 /****************************************************************************
45 * Lookup a nmb opcode name.
46 ****************************************************************************/
47 static char *lookup_opcode_name( int opcode )
49 struct opcode_names *op_namep;
52 for(i = 0; nmb_header_opcode_names[i].nmb_opcode_name != 0; i++) {
53 op_namep = &nmb_header_opcode_names[i];
54 if(opcode == op_namep->opcode)
55 return op_namep->nmb_opcode_name;
57 return "<unknown opcode>";
60 /****************************************************************************
61 print out a res_rec structure
62 ****************************************************************************/
63 static void debug_nmb_res_rec(struct res_rec *res, char *hdr)
67 DEBUGADD( 4, ( " %s: nmb_name=%s rr_type=%d rr_class=%d ttl=%d\n",
69 namestr(&res->rr_name),
74 if( res->rdlength == 0 || res->rdata == NULL )
77 for (i = 0; i < res->rdlength; i+= 16)
79 DEBUGADD(4, (" %s %3x char ", hdr, i));
81 for (j = 0; j < 16; j++)
83 unsigned char x = res->rdata[i+j];
84 if (x < 32 || x > 127) x = '.';
86 if (i+j >= res->rdlength) break;
87 DEBUGADD(4, ("%c", x));
90 DEBUGADD(4, (" hex "));
92 for (j = 0; j < 16; j++)
94 if (i+j >= res->rdlength) break;
95 DEBUGADD(4, ("%02X", (unsigned char)res->rdata[i+j]));
102 /****************************************************************************
104 ****************************************************************************/
105 void debug_nmb_packet(struct packet_struct *p)
107 struct nmb_packet *nmb = &p->packet.nmb;
111 dbgtext( "nmb packet from %s(%d) header: id=%d opcode=%s(%d) response=%s\n",
112 inet_ntoa(p->ip), p->port,
113 nmb->header.name_trn_id,
114 lookup_opcode_name(nmb->header.opcode),
116 BOOLSTR(nmb->header.response) );
117 dbgtext( " 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 dbgtext( " header: rcode=%d qdcount=%d ancount=%d nscount=%d arcount=%d\n",
128 nmb->header.arcount );
131 if (nmb->header.qdcount)
133 DEBUGADD( 4, ( " question: q_name=%s q_type=%d q_class=%d\n",
134 namestr(&nmb->question.question_name),
135 nmb->question.question_type,
136 nmb->question.question_class) );
139 if (nmb->answers && nmb->header.ancount)
141 debug_nmb_res_rec(nmb->answers,"answers");
143 if (nmb->nsrecs && nmb->header.nscount)
145 debug_nmb_res_rec(nmb->nsrecs,"nsrecs");
147 if (nmb->additional && nmb->header.arcount)
149 debug_nmb_res_rec(nmb->additional,"additional");
153 /*******************************************************************
154 handle "compressed" name pointers
155 ******************************************************************/
156 static BOOL handle_name_ptrs(unsigned char *ubuf,int *offset,int length,
157 BOOL *got_pointer,int *ret)
161 while ((ubuf[*offset] & 0xC0) == 0xC0) {
162 if (!*got_pointer) (*ret) += 2;
164 (*offset) = ((ubuf[*offset] & ~0xC0)<<8) | ubuf[(*offset)+1];
165 if (loop_count++ == 10 || (*offset) < 0 || (*offset)>(length-2)) {
172 /*******************************************************************
173 parse a nmb name from "compressed" format to something readable
174 return the space taken by the name, or 0 if the name is invalid
175 ******************************************************************/
176 static int parse_nmb_name(char *inbuf,int offset,int length, struct nmb_name *name)
179 unsigned char *ubuf = (unsigned char *)inbuf;
181 BOOL got_pointer=False;
183 if (length - offset < 2) return(0);
185 /* handle initial name pointers */
186 if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) return(0);
191 if ((m & 0xC0) || offset+m+2 > length) return(0);
193 bzero((char *)name,sizeof(*name));
195 /* the "compressed" part */
196 if (!got_pointer) ret += m + 2;
200 c1 = ubuf[offset++]-'A';
201 c2 = ubuf[offset++]-'A';
202 if ((c1 & 0xF0) || (c2 & 0xF0) || (n > sizeof(name->name)-1)) return(0);
203 name->name[n++] = (c1<<4) | c2;
209 /* parse out the name type,
210 its always in the 16th byte of the name */
211 name->name_type = ((unsigned char)name->name[15]) & 0xff;
213 /* remove trailing spaces */
216 while (n && name->name[n]==' ') name->name[n--] = 0;
219 /* now the domain parts (if any) */
221 while ((m=ubuf[offset])) {
222 /* we can have pointers within the domain part as well */
223 if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) return(0);
225 if (!got_pointer) ret += m+1;
226 if (n) name->scope[n++] = '.';
227 if (m+2+offset>length || n+m+1>sizeof(name->scope)) return(0);
229 while (m--) name->scope[n++] = (char)ubuf[offset++];
231 name->scope[n++] = 0;
237 /*******************************************************************
238 put a compressed nmb name into a buffer. return the length of the
241 compressed names are really weird. The "compression" doubles the
242 size. The idea is that it also means that compressed names conform
243 to the doman name system. See RFC1002.
244 ******************************************************************/
245 static int put_nmb_name(char *buf,int offset,struct nmb_name *name)
251 if (name->name[0] == '*') {
252 /* special case for wildcard name */
255 buf1[15] = name->name_type;
257 slprintf(buf1, sizeof(buf1) - 1,"%-15.15s%c",name->name,name->name_type);
265 buf[offset+1+2*m] = 'A' + ((buf1[m]>>4)&0xF);
266 buf[offset+2+2*m] = 'A' + (buf1[m]&0xF);
272 if (name->scope[0]) {
273 /* XXXX this scope handling needs testing */
274 ret += strlen(name->scope) + 1;
275 pstrcpy(&buf[offset+1],name->scope);
278 while ((p = strchr(p,'.'))) {
279 buf[offset] = PTR_DIFF(p,&buf[offset]);
280 offset += buf[offset];
283 buf[offset] = strlen(&buf[offset+1]);
289 /*******************************************************************
290 useful for debugging messages
291 ******************************************************************/
292 char *namestr(struct nmb_name *n)
295 static fstring ret[4];
299 slprintf(p,sizeof(fstring)-1, "%s<%02x>",n->name,n->name_type);
301 slprintf(p,sizeof(fstring)-1, "%s<%02x>.%s",n->name,n->name_type,n->scope);
307 /*******************************************************************
308 allocate and parse some resource records
309 ******************************************************************/
310 static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length,
311 struct res_rec **recs, int count)
314 *recs = (struct res_rec *)malloc(sizeof(**recs)*count);
315 if (!*recs) return(False);
317 bzero(*recs,sizeof(**recs)*count);
319 for (i=0;i<count;i++) {
320 int l = parse_nmb_name(inbuf,*offset,length,&(*recs)[i].rr_name);
322 if (!l || (*offset)+10 > length) {
326 (*recs)[i].rr_type = RSVAL(inbuf,(*offset));
327 (*recs)[i].rr_class = RSVAL(inbuf,(*offset)+2);
328 (*recs)[i].ttl = RIVAL(inbuf,(*offset)+4);
329 (*recs)[i].rdlength = RSVAL(inbuf,(*offset)+8);
331 if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) ||
332 (*offset)+(*recs)[i].rdlength > length) {
336 memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength);
337 (*offset) += (*recs)[i].rdlength;
342 /*******************************************************************
343 put a resource record into a packet
344 ******************************************************************/
345 static int put_res_rec(char *buf,int offset,struct res_rec *recs,int count)
350 for (i=0;i<count;i++) {
351 int l = put_nmb_name(buf,offset,&recs[i].rr_name);
354 RSSVAL(buf,offset,recs[i].rr_type);
355 RSSVAL(buf,offset+2,recs[i].rr_class);
356 RSIVAL(buf,offset+4,recs[i].ttl);
357 RSSVAL(buf,offset+8,recs[i].rdlength);
358 memcpy(buf+offset+10,recs[i].rdata,recs[i].rdlength);
359 offset += 10+recs[i].rdlength;
360 ret += 10+recs[i].rdlength;
366 /*******************************************************************
367 put a compressed name pointer record into a packet
368 ******************************************************************/
369 static int put_compressed_name_ptr(unsigned char *buf,int offset,struct res_rec *rec,int ptr_offset)
372 buf[offset] = (0xC0 | ((ptr_offset >> 8) & 0xFF));
373 buf[offset+1] = (ptr_offset & 0xFF);
376 RSSVAL(buf,offset,rec->rr_type);
377 RSSVAL(buf,offset+2,rec->rr_class);
378 RSIVAL(buf,offset+4,rec->ttl);
379 RSSVAL(buf,offset+8,rec->rdlength);
380 memcpy(buf+offset+10,rec->rdata,rec->rdlength);
381 offset += 10+rec->rdlength;
382 ret += 10+rec->rdlength;
387 /*******************************************************************
388 parse a dgram packet. Return False if the packet can't be parsed
389 or is invalid for some reason, True otherwise
391 this is documented in section 4.4.1 of RFC1002
392 ******************************************************************/
393 static BOOL parse_dgram(char *inbuf,int length,struct dgram_packet *dgram)
398 bzero((char *)dgram,sizeof(*dgram));
400 if (length < 14) return(False);
402 dgram->header.msg_type = CVAL(inbuf,0);
403 flags = CVAL(inbuf,1);
404 dgram->header.flags.node_type = (enum node_type)((flags>>2)&3);
405 if (flags & 1) dgram->header.flags.more = True;
406 if (flags & 2) dgram->header.flags.first = True;
407 dgram->header.dgm_id = RSVAL(inbuf,2);
408 putip((char *)&dgram->header.source_ip,inbuf+4);
409 dgram->header.source_port = RSVAL(inbuf,8);
410 dgram->header.dgm_length = RSVAL(inbuf,10);
411 dgram->header.packet_offset = RSVAL(inbuf,12);
415 if (dgram->header.msg_type == 0x10 ||
416 dgram->header.msg_type == 0x11 ||
417 dgram->header.msg_type == 0x12) {
418 offset += parse_nmb_name(inbuf,offset,length,&dgram->source_name);
419 offset += parse_nmb_name(inbuf,offset,length,&dgram->dest_name);
422 if (offset >= length || (length-offset > sizeof(dgram->data)))
425 dgram->datasize = length-offset;
426 memcpy(dgram->data,inbuf+offset,dgram->datasize);
432 /*******************************************************************
433 parse a nmb packet. Return False if the packet can't be parsed
434 or is invalid for some reason, True otherwise
435 ******************************************************************/
436 static BOOL parse_nmb(char *inbuf,int length,struct nmb_packet *nmb)
440 bzero((char *)nmb,sizeof(*nmb));
442 if (length < 12) return(False);
444 /* parse the header */
445 nmb->header.name_trn_id = RSVAL(inbuf,0);
447 DEBUG(10,("parse_nmb: packet id = %d\n", nmb->header.name_trn_id));
449 nmb->header.opcode = (CVAL(inbuf,2) >> 3) & 0xF;
450 nmb->header.response = ((CVAL(inbuf,2)>>7)&1)?True:False;
451 nm_flags = ((CVAL(inbuf,2) & 0x7) << 4) + (CVAL(inbuf,3)>>4);
452 nmb->header.nm_flags.bcast = (nm_flags&1)?True:False;
453 nmb->header.nm_flags.recursion_available = (nm_flags&8)?True:False;
454 nmb->header.nm_flags.recursion_desired = (nm_flags&0x10)?True:False;
455 nmb->header.nm_flags.trunc = (nm_flags&0x20)?True:False;
456 nmb->header.nm_flags.authoritative = (nm_flags&0x40)?True:False;
457 nmb->header.rcode = CVAL(inbuf,3) & 0xF;
458 nmb->header.qdcount = RSVAL(inbuf,4);
459 nmb->header.ancount = RSVAL(inbuf,6);
460 nmb->header.nscount = RSVAL(inbuf,8);
461 nmb->header.arcount = RSVAL(inbuf,10);
463 if (nmb->header.qdcount) {
464 offset = parse_nmb_name(inbuf,12,length,&nmb->question.question_name);
465 if (!offset) return(False);
467 if (length - (12+offset) < 4) return(False);
468 nmb->question.question_type = RSVAL(inbuf,12+offset);
469 nmb->question.question_class = RSVAL(inbuf,12+offset+2);
476 /* and any resource records */
477 if (nmb->header.ancount &&
478 !parse_alloc_res_rec(inbuf,&offset,length,&nmb->answers,
479 nmb->header.ancount))
482 if (nmb->header.nscount &&
483 !parse_alloc_res_rec(inbuf,&offset,length,&nmb->nsrecs,
484 nmb->header.nscount))
487 if (nmb->header.arcount &&
488 !parse_alloc_res_rec(inbuf,&offset,length,&nmb->additional,
489 nmb->header.arcount))
495 /*******************************************************************
496 'Copy constructor' for an nmb packet
497 ******************************************************************/
498 static struct packet_struct *copy_nmb_packet(struct packet_struct *packet)
500 struct nmb_packet *nmb;
501 struct nmb_packet *copy_nmb;
502 struct packet_struct *pkt_copy;
504 if(( pkt_copy = (struct packet_struct *)malloc(sizeof(*packet))) == NULL)
506 DEBUG(0,("copy_nmb_packet: malloc fail.\n"));
510 /* Structure copy of entire thing. */
514 /* Ensure this copy is not locked. */
515 pkt_copy->locked = False;
517 /* Ensure this copy has no resource records. */
518 nmb = &packet->packet.nmb;
519 copy_nmb = &pkt_copy->packet.nmb;
521 copy_nmb->answers = NULL;
522 copy_nmb->nsrecs = NULL;
523 copy_nmb->additional = NULL;
525 /* Now copy any resource records. */
529 if((copy_nmb->answers = (struct res_rec *)
530 malloc(nmb->header.ancount * sizeof(struct res_rec))) == NULL)
532 memcpy((char *)copy_nmb->answers, (char *)nmb->answers,
533 nmb->header.ancount * sizeof(struct res_rec));
537 if((copy_nmb->nsrecs = (struct res_rec *)
538 malloc(nmb->header.nscount * sizeof(struct res_rec))) == NULL)
540 memcpy((char *)copy_nmb->nsrecs, (char *)nmb->nsrecs,
541 nmb->header.nscount * sizeof(struct res_rec));
545 if((copy_nmb->additional = (struct res_rec *)
546 malloc(nmb->header.arcount * sizeof(struct res_rec))) == NULL)
548 memcpy((char *)copy_nmb->additional, (char *)nmb->additional,
549 nmb->header.arcount * sizeof(struct res_rec));
556 if(copy_nmb->answers)
557 free((char *)copy_nmb->answers);
559 free((char *)copy_nmb->nsrecs);
560 if(copy_nmb->additional)
561 free((char *)copy_nmb->additional);
562 free((char *)pkt_copy);
564 DEBUG(0,("copy_nmb_packet: malloc fail in resource records.\n"));
568 /*******************************************************************
569 'Copy constructor' for a dgram packet
570 ******************************************************************/
571 static struct packet_struct *copy_dgram_packet(struct packet_struct *packet)
573 struct packet_struct *pkt_copy;
575 if(( pkt_copy = (struct packet_struct *)malloc(sizeof(*packet))) == NULL)
577 DEBUG(0,("copy_dgram_packet: malloc fail.\n"));
581 /* Structure copy of entire thing. */
585 /* Ensure this copy is not locked. */
586 pkt_copy->locked = False;
588 /* There are no additional pointers in a dgram packet,
593 /*******************************************************************
594 'Copy constructor' for a generic packet
595 ******************************************************************/
596 struct packet_struct *copy_packet(struct packet_struct *packet)
598 if(packet->packet_type == NMB_PACKET)
599 return copy_nmb_packet(packet);
600 else if (packet->packet_type == DGRAM_PACKET)
601 return copy_dgram_packet(packet);
605 /*******************************************************************
606 free up any resources associated with an nmb packet
607 ******************************************************************/
608 static void free_nmb_packet(struct nmb_packet *nmb)
610 if (nmb->answers) free(nmb->answers);
611 if (nmb->nsrecs) free(nmb->nsrecs);
612 if (nmb->additional) free(nmb->additional);
615 /*******************************************************************
616 free up any resources associated with a dgram packet
617 ******************************************************************/
618 static void free_dgram_packet(struct dgram_packet *nmb)
620 /* We have nothing to do for a dgram packet. */
623 /*******************************************************************
624 free up any resources associated with a packet
625 ******************************************************************/
626 void free_packet(struct packet_struct *packet)
630 if (packet->packet_type == NMB_PACKET)
631 free_nmb_packet(&packet->packet.nmb);
632 else if (packet->packet_type == DGRAM_PACKET)
633 free_dgram_packet(&packet->packet.dgram);
637 /*******************************************************************
638 read a packet from a socket and parse it, returning a packet ready
639 to be used or put on the queue. This assumes a UDP socket
640 ******************************************************************/
641 struct packet_struct *read_packet(int fd,enum packet_type packet_type)
643 extern struct in_addr lastip;
645 struct packet_struct *packet;
646 char buf[MAX_DGRAM_SIZE];
650 length = read_udp_socket(fd,buf,sizeof(buf));
651 if (length < MIN_DGRAM_SIZE) return(NULL);
653 packet = (struct packet_struct *)malloc(sizeof(*packet));
654 if (!packet) return(NULL);
659 packet->port = lastport;
661 packet->locked = False;
662 packet->timestamp = time(NULL);
663 packet->packet_type = packet_type;
667 ok = parse_nmb(buf,length,&packet->packet.nmb);
671 ok = parse_dgram(buf,length,&packet->packet.dgram);
675 DEBUG(10,("parse_nmb: discarding packet id = %d\n",
676 packet->packet.nmb.header.name_trn_id));
683 DEBUG(5,("Received a packet of len %d from (%s) port %d\n",
684 length, inet_ntoa(packet->ip), packet->port ) );
690 /*******************************************************************
691 send a udp packet on a already open socket
692 ******************************************************************/
693 static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port)
696 struct sockaddr_in sock_out;
698 /* set the address and port */
699 bzero((char *)&sock_out,sizeof(sock_out));
700 putip((char *)&sock_out.sin_addr,(char *)&ip);
701 sock_out.sin_port = htons( port );
702 sock_out.sin_family = AF_INET;
704 DEBUG( 5, ( "Sending a packet of len %d to (%s) on port %d\n",
705 len, inet_ntoa(ip), port ) );
707 ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out,
708 sizeof(sock_out)) >= 0);
711 DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n",
712 inet_ntoa(ip),port,strerror(errno)));
720 /*******************************************************************
721 build a dgram packet ready for sending
723 XXXX This currently doesn't handle packets too big for one
724 datagram. It should split them and use the packet_offset, more and
725 first flags to handle the fragmentation. Yuck.
726 ******************************************************************/
727 static int build_dgram(char *buf,struct packet_struct *p)
729 struct dgram_packet *dgram = &p->packet.dgram;
730 unsigned char *ubuf = (unsigned char *)buf;
733 /* put in the header */
734 ubuf[0] = dgram->header.msg_type;
735 ubuf[1] = (((int)dgram->header.flags.node_type)<<2);
736 if (dgram->header.flags.more) ubuf[1] |= 1;
737 if (dgram->header.flags.first) ubuf[1] |= 2;
738 RSSVAL(ubuf,2,dgram->header.dgm_id);
739 putip(ubuf+4,(char *)&dgram->header.source_ip);
740 RSSVAL(ubuf,8,dgram->header.source_port);
741 RSSVAL(ubuf,12,dgram->header.packet_offset);
745 if (dgram->header.msg_type == 0x10 ||
746 dgram->header.msg_type == 0x11 ||
747 dgram->header.msg_type == 0x12) {
748 offset += put_nmb_name((char *)ubuf,offset,&dgram->source_name);
749 offset += put_nmb_name((char *)ubuf,offset,&dgram->dest_name);
752 memcpy(ubuf+offset,dgram->data,dgram->datasize);
753 offset += dgram->datasize;
755 /* automatically set the dgm_length */
756 dgram->header.dgm_length = offset;
757 RSSVAL(ubuf,10,dgram->header.dgm_length);
762 /*******************************************************************
764 *******************************************************************/
765 void make_nmb_name( struct nmb_name *n, char *name, int type, char *this_scope )
767 memset( (char *)n, '\0', sizeof(struct nmb_name) );
768 StrnCpy( n->name, name, 15 );
770 n->name_type = (unsigned int)type & 0xFF;
771 StrnCpy( n->scope, this_scope, 63 );
772 strupper( n->scope );
775 /*******************************************************************
776 Compare two nmb names
777 ******************************************************************/
779 BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2)
781 return ((n1->name_type == n2->name_type) &&
782 strequal(n1->name ,n2->name ) &&
783 strequal(n1->scope,n2->scope));
786 /*******************************************************************
787 build a nmb packet ready for sending
789 XXXX this currently relies on not being passed something that expands
790 to a packet too big for the buffer. Eventually this should be
791 changed to set the trunc bit so the receiver can request the rest
792 via tcp (when that becomes supported)
793 ******************************************************************/
794 static int build_nmb(char *buf,struct packet_struct *p)
796 struct nmb_packet *nmb = &p->packet.nmb;
797 unsigned char *ubuf = (unsigned char *)buf;
800 /* put in the header */
801 RSSVAL(ubuf,offset,nmb->header.name_trn_id);
802 ubuf[offset+2] = (nmb->header.opcode & 0xF) << 3;
803 if (nmb->header.response) ubuf[offset+2] |= (1<<7);
804 if (nmb->header.nm_flags.authoritative &&
805 nmb->header.response) ubuf[offset+2] |= 0x4;
806 if (nmb->header.nm_flags.trunc) ubuf[offset+2] |= 0x2;
807 if (nmb->header.nm_flags.recursion_desired) ubuf[offset+2] |= 0x1;
808 if (nmb->header.nm_flags.recursion_available &&
809 nmb->header.response) ubuf[offset+3] |= 0x80;
810 if (nmb->header.nm_flags.bcast) ubuf[offset+3] |= 0x10;
811 ubuf[offset+3] |= (nmb->header.rcode & 0xF);
813 RSSVAL(ubuf,offset+4,nmb->header.qdcount);
814 RSSVAL(ubuf,offset+6,nmb->header.ancount);
815 RSSVAL(ubuf,offset+8,nmb->header.nscount);
816 RSSVAL(ubuf,offset+10,nmb->header.arcount);
819 if (nmb->header.qdcount) {
820 /* XXXX this doesn't handle a qdcount of > 1 */
821 offset += put_nmb_name((char *)ubuf,offset,&nmb->question.question_name);
822 RSSVAL(ubuf,offset,nmb->question.question_type);
823 RSSVAL(ubuf,offset+2,nmb->question.question_class);
827 if (nmb->header.ancount)
828 offset += put_res_rec((char *)ubuf,offset,nmb->answers,
829 nmb->header.ancount);
831 if (nmb->header.nscount)
832 offset += put_res_rec((char *)ubuf,offset,nmb->nsrecs,
833 nmb->header.nscount);
836 * The spec says we must put compressed name pointers
837 * in the following outgoing packets :
838 * NAME_REGISTRATION_REQUEST, NAME_REFRESH_REQUEST,
839 * NAME_RELEASE_REQUEST.
842 if((nmb->header.response == False) &&
843 ((nmb->header.opcode == NMB_NAME_REG_OPCODE) ||
844 (nmb->header.opcode == NMB_NAME_RELEASE_OPCODE) ||
845 (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_8) ||
846 (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_9) ||
847 (nmb->header.opcode == NMB_NAME_MULTIHOMED_REG_OPCODE)) &&
848 (nmb->header.arcount == 1)) {
850 offset += put_compressed_name_ptr(ubuf,offset,nmb->additional,12);
852 } else if (nmb->header.arcount) {
853 offset += put_res_rec((char *)ubuf,offset,nmb->additional,
854 nmb->header.arcount);
860 /*******************************************************************
862 ******************************************************************/
863 BOOL send_packet(struct packet_struct *p)
868 bzero(buf,sizeof(buf));
870 switch (p->packet_type)
873 len = build_nmb(buf,p);
878 len = build_dgram(buf,p);
882 if (!len) return(False);
884 return(send_udp(p->fd,buf,len,p->ip,p->port));
887 /****************************************************************************
888 receive a packet with timeout on a open UDP filedescriptor
889 The timeout is in milliseconds
890 ***************************************************************************/
891 struct packet_struct *receive_packet(int fd,enum packet_type type,int t)
894 struct timeval timeout;
898 timeout.tv_sec = t/1000;
899 timeout.tv_usec = 1000*(t%1000);
901 sys_select(fd+1,&fds,&timeout);
903 if (FD_ISSET(fd,&fds))
904 return(read_packet(fd,type));
910 /****************************************************************************
911 return the number of bits that match between two 4 character buffers
912 ***************************************************************************/
913 static int matching_bits(uchar *p1, uchar *p2)
916 for (i=0; i<4; i++) {
917 if (p1[i] != p2[i]) break;
921 if (i==4) return ret;
923 for (j=0; j<8; j++) {
924 if ((p1[i] & (1<<(7-j))) != (p2[i] & (1<<(7-j)))) break;
932 static uchar sort_ip[4];
934 /****************************************************************************
935 compare two query reply records
936 ***************************************************************************/
937 static int name_query_comp(uchar *p1, uchar *p2)
939 return matching_bits(p2+2, sort_ip) - matching_bits(p1+2, sort_ip);
942 /****************************************************************************
943 sort a set of 6 byte name query response records so that the IPs that
944 have the most leading bits in common with the specified address come first
945 ***************************************************************************/
946 void sort_query_replies(char *data, int n, struct in_addr ip)
950 putip(sort_ip, (char *)&ip);
952 qsort(data, n, 6, QSORT_CAST name_query_comp);