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 nmb_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 nmb_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 (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);
226 if (!got_pointer) ret += m+1;
227 if (n) name->scope[n++] = '.';
228 if (m+2+offset>length || n+m+1>sizeof(name->scope)) return(0);
230 while (m--) name->scope[n++] = (char)ubuf[offset++];
232 name->scope[n++] = 0;
238 /*******************************************************************
239 put a compressed nmb name into a buffer. return the length of the
242 compressed names are really weird. The "compression" doubles the
243 size. The idea is that it also means that compressed names conform
244 to the doman name system. See RFC1002.
245 ******************************************************************/
246 static int put_nmb_name(char *buf,int offset,struct nmb_name *name)
252 if (strcmp(name->name,"*") == 0) {
253 /* special case for wildcard name */
256 buf1[15] = name->name_type;
258 slprintf(buf1, sizeof(buf1) - 1,"%-15.15s%c",name->name,name->name_type);
266 buf[offset+1+2*m] = 'A' + ((buf1[m]>>4)&0xF);
267 buf[offset+2+2*m] = 'A' + (buf1[m]&0xF);
273 if (name->scope[0]) {
274 /* XXXX this scope handling needs testing */
275 ret += strlen(name->scope) + 1;
276 pstrcpy(&buf[offset+1],name->scope);
279 while ((p = strchr(p,'.'))) {
280 buf[offset] = PTR_DIFF(p,&buf[offset]);
281 offset += buf[offset];
284 buf[offset] = strlen(&buf[offset+1]);
291 /*******************************************************************
292 useful for debugging messages
293 ******************************************************************/
294 char *nmb_namestr(struct nmb_name *n)
297 static fstring ret[4];
300 nmb_safe_namestr(n, p, sizeof(fstring));
306 /*******************************************************************
307 useful for debugging messages
308 ******************************************************************/
309 void nmb_safe_namestr(struct nmb_name *n, char *str, size_t len)
312 slprintf(str, len-1, "%s<%02x>",n->name,n->name_type);
314 slprintf(str, len-1, "%s<%02x>.%s",n->name,n->name_type,n->scope);
317 /*******************************************************************
318 allocate and parse some resource records
319 ******************************************************************/
320 static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length,
321 struct res_rec **recs, int count)
324 *recs = (struct res_rec *)malloc(sizeof(**recs)*count);
325 if (!*recs) return(False);
327 bzero(*recs,sizeof(**recs)*count);
329 for (i=0;i<count;i++) {
330 int l = parse_nmb_name(inbuf,*offset,length,&(*recs)[i].rr_name);
332 if (!l || (*offset)+10 > length) {
336 (*recs)[i].rr_type = RSVAL(inbuf,(*offset));
337 (*recs)[i].rr_class = RSVAL(inbuf,(*offset)+2);
338 (*recs)[i].ttl = RIVAL(inbuf,(*offset)+4);
339 (*recs)[i].rdlength = RSVAL(inbuf,(*offset)+8);
341 if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) ||
342 (*offset)+(*recs)[i].rdlength > length) {
346 memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength);
347 (*offset) += (*recs)[i].rdlength;
352 /*******************************************************************
353 put a resource record into a packet
354 ******************************************************************/
355 static int put_res_rec(char *buf,int offset,struct res_rec *recs,int count)
360 for (i=0;i<count;i++) {
361 int l = put_nmb_name(buf,offset,&recs[i].rr_name);
364 RSSVAL(buf,offset,recs[i].rr_type);
365 RSSVAL(buf,offset+2,recs[i].rr_class);
366 RSIVAL(buf,offset+4,recs[i].ttl);
367 RSSVAL(buf,offset+8,recs[i].rdlength);
368 memcpy(buf+offset+10,recs[i].rdata,recs[i].rdlength);
369 offset += 10+recs[i].rdlength;
370 ret += 10+recs[i].rdlength;
376 /*******************************************************************
377 put a compressed name pointer record into a packet
378 ******************************************************************/
379 static int put_compressed_name_ptr(unsigned char *buf,int offset,struct res_rec *rec,int ptr_offset)
382 buf[offset] = (0xC0 | ((ptr_offset >> 8) & 0xFF));
383 buf[offset+1] = (ptr_offset & 0xFF);
386 RSSVAL(buf,offset,rec->rr_type);
387 RSSVAL(buf,offset+2,rec->rr_class);
388 RSIVAL(buf,offset+4,rec->ttl);
389 RSSVAL(buf,offset+8,rec->rdlength);
390 memcpy(buf+offset+10,rec->rdata,rec->rdlength);
391 offset += 10+rec->rdlength;
392 ret += 10+rec->rdlength;
397 /*******************************************************************
398 parse a dgram packet. Return False if the packet can't be parsed
399 or is invalid for some reason, True otherwise
401 this is documented in section 4.4.1 of RFC1002
402 ******************************************************************/
403 static BOOL parse_dgram(char *inbuf,int length,struct dgram_packet *dgram)
408 bzero((char *)dgram,sizeof(*dgram));
410 if (length < 14) return(False);
412 dgram->header.msg_type = CVAL(inbuf,0);
413 flags = CVAL(inbuf,1);
414 dgram->header.flags.node_type = (enum node_type)((flags>>2)&3);
415 if (flags & 1) dgram->header.flags.more = True;
416 if (flags & 2) dgram->header.flags.first = True;
417 dgram->header.dgm_id = RSVAL(inbuf,2);
418 putip((char *)&dgram->header.source_ip,inbuf+4);
419 dgram->header.source_port = RSVAL(inbuf,8);
420 dgram->header.dgm_length = RSVAL(inbuf,10);
421 dgram->header.packet_offset = RSVAL(inbuf,12);
425 if (dgram->header.msg_type == 0x10 ||
426 dgram->header.msg_type == 0x11 ||
427 dgram->header.msg_type == 0x12) {
428 offset += parse_nmb_name(inbuf,offset,length,&dgram->source_name);
429 offset += parse_nmb_name(inbuf,offset,length,&dgram->dest_name);
432 if (offset >= length || (length-offset > sizeof(dgram->data)))
435 dgram->datasize = length-offset;
436 memcpy(dgram->data,inbuf+offset,dgram->datasize);
442 /*******************************************************************
443 parse a nmb packet. Return False if the packet can't be parsed
444 or is invalid for some reason, True otherwise
445 ******************************************************************/
446 static BOOL parse_nmb(char *inbuf,int length,struct nmb_packet *nmb)
450 bzero((char *)nmb,sizeof(*nmb));
452 if (length < 12) return(False);
454 /* parse the header */
455 nmb->header.name_trn_id = RSVAL(inbuf,0);
457 DEBUG(10,("parse_nmb: packet id = %d\n", nmb->header.name_trn_id));
459 nmb->header.opcode = (CVAL(inbuf,2) >> 3) & 0xF;
460 nmb->header.response = ((CVAL(inbuf,2)>>7)&1)?True:False;
461 nm_flags = ((CVAL(inbuf,2) & 0x7) << 4) + (CVAL(inbuf,3)>>4);
462 nmb->header.nm_flags.bcast = (nm_flags&1)?True:False;
463 nmb->header.nm_flags.recursion_available = (nm_flags&8)?True:False;
464 nmb->header.nm_flags.recursion_desired = (nm_flags&0x10)?True:False;
465 nmb->header.nm_flags.trunc = (nm_flags&0x20)?True:False;
466 nmb->header.nm_flags.authoritative = (nm_flags&0x40)?True:False;
467 nmb->header.rcode = CVAL(inbuf,3) & 0xF;
468 nmb->header.qdcount = RSVAL(inbuf,4);
469 nmb->header.ancount = RSVAL(inbuf,6);
470 nmb->header.nscount = RSVAL(inbuf,8);
471 nmb->header.arcount = RSVAL(inbuf,10);
473 if (nmb->header.qdcount) {
474 offset = parse_nmb_name(inbuf,12,length,&nmb->question.question_name);
475 if (!offset) return(False);
477 if (length - (12+offset) < 4) return(False);
478 nmb->question.question_type = RSVAL(inbuf,12+offset);
479 nmb->question.question_class = RSVAL(inbuf,12+offset+2);
486 /* and any resource records */
487 if (nmb->header.ancount &&
488 !parse_alloc_res_rec(inbuf,&offset,length,&nmb->answers,
489 nmb->header.ancount))
492 if (nmb->header.nscount &&
493 !parse_alloc_res_rec(inbuf,&offset,length,&nmb->nsrecs,
494 nmb->header.nscount))
497 if (nmb->header.arcount &&
498 !parse_alloc_res_rec(inbuf,&offset,length,&nmb->additional,
499 nmb->header.arcount))
505 /*******************************************************************
506 'Copy constructor' for an nmb packet
507 ******************************************************************/
508 static struct packet_struct *copy_nmb_packet(struct packet_struct *packet)
510 struct nmb_packet *nmb;
511 struct nmb_packet *copy_nmb;
512 struct packet_struct *pkt_copy;
514 if(( pkt_copy = (struct packet_struct *)malloc(sizeof(*packet))) == NULL)
516 DEBUG(0,("copy_nmb_packet: malloc fail.\n"));
520 /* Structure copy of entire thing. */
524 /* Ensure this copy is not locked. */
525 pkt_copy->locked = False;
527 /* Ensure this copy has no resource records. */
528 nmb = &packet->packet.nmb;
529 copy_nmb = &pkt_copy->packet.nmb;
531 copy_nmb->answers = NULL;
532 copy_nmb->nsrecs = NULL;
533 copy_nmb->additional = NULL;
535 /* Now copy any resource records. */
539 if((copy_nmb->answers = (struct res_rec *)
540 malloc(nmb->header.ancount * sizeof(struct res_rec))) == NULL)
542 memcpy((char *)copy_nmb->answers, (char *)nmb->answers,
543 nmb->header.ancount * sizeof(struct res_rec));
547 if((copy_nmb->nsrecs = (struct res_rec *)
548 malloc(nmb->header.nscount * sizeof(struct res_rec))) == NULL)
550 memcpy((char *)copy_nmb->nsrecs, (char *)nmb->nsrecs,
551 nmb->header.nscount * sizeof(struct res_rec));
555 if((copy_nmb->additional = (struct res_rec *)
556 malloc(nmb->header.arcount * sizeof(struct res_rec))) == NULL)
558 memcpy((char *)copy_nmb->additional, (char *)nmb->additional,
559 nmb->header.arcount * sizeof(struct res_rec));
566 if(copy_nmb->answers)
567 free((char *)copy_nmb->answers);
569 free((char *)copy_nmb->nsrecs);
570 if(copy_nmb->additional)
571 free((char *)copy_nmb->additional);
572 free((char *)pkt_copy);
574 DEBUG(0,("copy_nmb_packet: malloc fail in resource records.\n"));
578 /*******************************************************************
579 'Copy constructor' for a dgram packet
580 ******************************************************************/
581 static struct packet_struct *copy_dgram_packet(struct packet_struct *packet)
583 struct packet_struct *pkt_copy;
585 if(( pkt_copy = (struct packet_struct *)malloc(sizeof(*packet))) == NULL)
587 DEBUG(0,("copy_dgram_packet: malloc fail.\n"));
591 /* Structure copy of entire thing. */
595 /* Ensure this copy is not locked. */
596 pkt_copy->locked = False;
598 /* There are no additional pointers in a dgram packet,
603 /*******************************************************************
604 'Copy constructor' for a generic packet
605 ******************************************************************/
606 struct packet_struct *copy_packet(struct packet_struct *packet)
608 if(packet->packet_type == NMB_PACKET)
609 return copy_nmb_packet(packet);
610 else if (packet->packet_type == DGRAM_PACKET)
611 return copy_dgram_packet(packet);
615 /*******************************************************************
616 free up any resources associated with an nmb packet
617 ******************************************************************/
618 static void free_nmb_packet(struct nmb_packet *nmb)
620 if (nmb->answers) free(nmb->answers);
621 if (nmb->nsrecs) free(nmb->nsrecs);
622 if (nmb->additional) free(nmb->additional);
625 /*******************************************************************
626 free up any resources associated with a dgram packet
627 ******************************************************************/
628 static void free_dgram_packet(struct dgram_packet *nmb)
630 /* We have nothing to do for a dgram packet. */
633 /*******************************************************************
634 free up any resources associated with a packet
635 ******************************************************************/
636 void free_packet(struct packet_struct *packet)
640 if (packet->packet_type == NMB_PACKET)
641 free_nmb_packet(&packet->packet.nmb);
642 else if (packet->packet_type == DGRAM_PACKET)
643 free_dgram_packet(&packet->packet.dgram);
647 /*******************************************************************
648 read a packet from a socket and parse it, returning a packet ready
649 to be used or put on the queue. This assumes a UDP socket
650 ******************************************************************/
651 struct packet_struct *read_packet(int fd,enum packet_type packet_type)
653 extern struct in_addr lastip;
654 struct nmb_state con;
656 struct packet_struct *packet;
657 char buf[MAX_DGRAM_SIZE];
661 if (packet_type == NMB_SOCK_PACKET || packet_type == DGRAM_SOCK_PACKET)
664 if (!read_nmb_sock(fd, &con))
668 if (write(fd, &trn_id, sizeof(trn_id)) != sizeof(trn_id))
674 length = read_udp_socket(fd,buf,sizeof(buf));
676 dump_data(100, buf, length);
678 if (packet_type == NMB_SOCK_PACKET || packet_type == DGRAM_SOCK_PACKET)
681 if (write(fd, &trn_id, sizeof(trn_id)) != sizeof(trn_id))
687 if (length < MIN_DGRAM_SIZE) return(NULL);
689 if (packet_type == NMB_SOCK_PACKET || packet_type == DGRAM_SOCK_PACKET)
695 packet = (struct packet_struct *)malloc(sizeof(*packet));
696 if (!packet) return(NULL);
701 packet->port = lastport;
703 packet->locked = False;
704 packet->timestamp = time(NULL);
705 packet->packet_type = packet_type;
709 case NMB_SOCK_PACKET:
710 ok = parse_nmb(buf,length,&packet->packet.nmb);
714 case DGRAM_SOCK_PACKET:
715 ok = parse_dgram(buf,length,&packet->packet.dgram);
719 DEBUG(10,("read_packet: discarding packet id = %d\n",
720 packet->packet.nmb.header.name_trn_id));
727 DEBUG(5,("Received a packet of len %d from (%s) port %d\n",
728 length, inet_ntoa(packet->ip), packet->port ) );
734 /*******************************************************************
735 send a udp packet on a already open socket
736 ******************************************************************/
737 static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port)
740 struct sockaddr_in sock_out;
742 /* set the address and port */
743 bzero((char *)&sock_out,sizeof(sock_out));
744 putip((char *)&sock_out.sin_addr,(char *)&ip);
745 sock_out.sin_port = htons( port );
746 sock_out.sin_family = AF_INET;
748 DEBUG( 5, ( "Sending a packet of len %d to (%s) on port %d\n",
749 len, inet_ntoa(ip), port ) );
751 ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out,
752 sizeof(sock_out)) >= 0);
755 DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n",
756 inet_ntoa(ip),port,strerror(errno)));
764 /*******************************************************************
765 build a dgram packet ready for sending
767 XXXX This currently doesn't handle packets too big for one
768 datagram. It should split them and use the packet_offset, more and
769 first flags to handle the fragmentation. Yuck.
770 ******************************************************************/
771 static int build_dgram(char *buf,struct packet_struct *p)
773 struct dgram_packet *dgram = &p->packet.dgram;
774 unsigned char *ubuf = (unsigned char *)buf;
777 /* put in the header */
778 ubuf[0] = dgram->header.msg_type;
779 ubuf[1] = (((unsigned int)dgram->header.flags.node_type)<<2);
780 if (dgram->header.flags.more) ubuf[1] |= 1;
781 if (dgram->header.flags.first) ubuf[1] |= 2;
782 RSSVAL(ubuf,2,dgram->header.dgm_id);
783 putip(ubuf+4,(char *)&dgram->header.source_ip);
784 RSSVAL(ubuf,8,dgram->header.source_port);
785 RSSVAL(ubuf,12,dgram->header.packet_offset);
789 if (dgram->header.msg_type == 0x10 ||
790 dgram->header.msg_type == 0x11 ||
791 dgram->header.msg_type == 0x12) {
792 offset += put_nmb_name((char *)ubuf,offset,&dgram->source_name);
793 offset += put_nmb_name((char *)ubuf,offset,&dgram->dest_name);
796 memcpy(ubuf+offset,dgram->data,dgram->datasize);
797 offset += dgram->datasize;
799 /* automatically set the dgm_length */
800 dgram->header.dgm_length = offset;
801 RSSVAL(ubuf,10,dgram->header.dgm_length);
806 /*******************************************************************
808 *******************************************************************/
809 void make_nmb_name( struct nmb_name *n, const char *name, int type, const char *this_scope )
811 memset( (char *)n, '\0', sizeof(struct nmb_name) );
812 StrnCpy( n->name, name, 15 );
814 n->name_type = (unsigned int)type & 0xFF;
815 StrnCpy( n->scope, this_scope, 63 );
816 strupper( n->scope );
819 /*******************************************************************
820 Compare two nmb names
821 ******************************************************************/
823 BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2)
825 return ((n1->name_type == n2->name_type) &&
826 strequal(n1->name ,n2->name ) &&
827 strequal(n1->scope,n2->scope));
830 /*******************************************************************
831 build a nmb packet ready for sending
833 XXXX this currently relies on not being passed something that expands
834 to a packet too big for the buffer. Eventually this should be
835 changed to set the trunc bit so the receiver can request the rest
836 via tcp (when that becomes supported)
837 ******************************************************************/
838 static int build_nmb(char *buf,struct packet_struct *p)
840 struct nmb_packet *nmb = &p->packet.nmb;
841 unsigned char *ubuf = (unsigned char *)buf;
844 /* put in the header */
845 RSSVAL(ubuf,offset,nmb->header.name_trn_id);
846 ubuf[offset+2] = (nmb->header.opcode & 0xF) << 3;
847 if (nmb->header.response) ubuf[offset+2] |= (1<<7);
848 if (nmb->header.nm_flags.authoritative &&
849 nmb->header.response) ubuf[offset+2] |= 0x4;
850 if (nmb->header.nm_flags.trunc) ubuf[offset+2] |= 0x2;
851 if (nmb->header.nm_flags.recursion_desired) ubuf[offset+2] |= 0x1;
852 if (nmb->header.nm_flags.recursion_available &&
853 nmb->header.response) ubuf[offset+3] |= 0x80;
854 if (nmb->header.nm_flags.bcast) ubuf[offset+3] |= 0x10;
855 ubuf[offset+3] |= (nmb->header.rcode & 0xF);
857 RSSVAL(ubuf,offset+4,nmb->header.qdcount);
858 RSSVAL(ubuf,offset+6,nmb->header.ancount);
859 RSSVAL(ubuf,offset+8,nmb->header.nscount);
860 RSSVAL(ubuf,offset+10,nmb->header.arcount);
863 if (nmb->header.qdcount) {
864 /* XXXX this doesn't handle a qdcount of > 1 */
865 offset += put_nmb_name((char *)ubuf,offset,&nmb->question.question_name);
866 RSSVAL(ubuf,offset,nmb->question.question_type);
867 RSSVAL(ubuf,offset+2,nmb->question.question_class);
871 if (nmb->header.ancount)
872 offset += put_res_rec((char *)ubuf,offset,nmb->answers,
873 nmb->header.ancount);
875 if (nmb->header.nscount)
876 offset += put_res_rec((char *)ubuf,offset,nmb->nsrecs,
877 nmb->header.nscount);
880 * The spec says we must put compressed name pointers
881 * in the following outgoing packets :
882 * NAME_REGISTRATION_REQUEST, NAME_REFRESH_REQUEST,
883 * NAME_RELEASE_REQUEST.
886 if((nmb->header.response == False) &&
887 ((nmb->header.opcode == NMB_NAME_REG_OPCODE) ||
888 (nmb->header.opcode == NMB_NAME_RELEASE_OPCODE) ||
889 (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_8) ||
890 (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_9) ||
891 (nmb->header.opcode == NMB_NAME_MULTIHOMED_REG_OPCODE)) &&
892 (nmb->header.arcount == 1)) {
894 offset += put_compressed_name_ptr(ubuf,offset,nmb->additional,12);
896 } else if (nmb->header.arcount) {
897 offset += put_res_rec((char *)ubuf,offset,nmb->additional,
898 nmb->header.arcount);
904 /*******************************************************************
906 ******************************************************************/
907 BOOL send_packet(struct packet_struct *p)
912 DEBUG(100,("send_packet: %d %d\n", p->fd, p->packet_type));
914 bzero(buf,sizeof(buf));
916 switch (p->packet_type)
919 case NMB_SOCK_PACKET:
920 len = build_nmb(buf,p);
925 case DGRAM_SOCK_PACKET:
926 len = build_dgram(buf,p);
930 if (!len) return(False);
932 switch (p->packet_type)
936 return(send_udp(p->fd,buf,len,p->ip,p->port));
939 case NMB_SOCK_PACKET:
940 case DGRAM_SOCK_PACKET:
943 struct nmb_state nmb;
955 memcpy(q, &nmb, sizeof(nmb));
958 qlen = PTR_DIFF(q, qbuf);
959 SIVAL(qbuf, 0, qlen);
961 dump_data(100, qbuf, qlen);
963 if (write(p->fd,qbuf,qlen) != qlen)
965 DEBUG(0,("send_packet: write hdr failed\n"));
968 if (read(p->fd, &trn_id, sizeof(trn_id)) != sizeof(trn_id))
970 DEBUG(0,("send_packet: 1st ack failed\n"));
973 if (write(p->fd,buf,len) != len)
975 DEBUG(0,("send_packet: write packet failed\n"));
978 if (read(p->fd, &trn_id, sizeof(trn_id)) != sizeof(trn_id))
980 DEBUG(0,("send_packet: 2nd ack failed\n"));
990 /****************************************************************************
991 receive a packet with timeout on a open UDP filedescriptor
992 The timeout is in milliseconds
993 ***************************************************************************/
994 struct packet_struct *receive_packet(int fd,enum packet_type type,int t)
997 struct timeval timeout;
1001 timeout.tv_sec = t/1000;
1002 timeout.tv_usec = 1000*(t%1000);
1004 DEBUG(100,("receive_packet: %d %d\n", fd, type));
1005 sys_select(fd+1,&fds,NULL, &timeout);
1007 if (FD_ISSET(fd,&fds))
1008 return(read_packet(fd,type));
1014 /****************************************************************************
1015 return the number of bits that match between two 4 character buffers
1016 ***************************************************************************/
1017 static int matching_bits(uchar *p1, uchar *p2)
1020 for (i=0; i<4; i++) {
1021 if (p1[i] != p2[i]) break;
1025 if (i==4) return ret;
1027 for (j=0; j<8; j++) {
1028 if ((p1[i] & (1<<(7-j))) != (p2[i] & (1<<(7-j)))) break;
1036 static uchar sort_ip[4];
1038 /****************************************************************************
1039 compare two query reply records
1040 ***************************************************************************/
1041 static int name_query_comp(uchar *p1, uchar *p2)
1043 return matching_bits(p2+2, sort_ip) - matching_bits(p1+2, sort_ip);
1046 /****************************************************************************
1047 sort a set of 6 byte name query response records so that the IPs that
1048 have the most leading bits in common with the specified address come first
1049 ***************************************************************************/
1050 void sort_query_replies(char *data, int n, struct in_addr ip)
1054 putip(sort_ip, (char *)&ip);
1056 qsort(data, n, 6, QSORT_CAST name_query_comp);
1059 BOOL read_nmb_sock(int c, struct nmb_state *con)
1070 rl = read(c, &buf, sizeof(len));
1074 DEBUG(0,("read_nmb_sock: error\n"));
1077 if (rl != sizeof(len))
1079 DEBUG(0,("Unable to read length\n"));
1080 dump_data(0, buf, sizeof(len));
1086 if (len > sizeof(buf))
1088 DEBUG(0,("length %d too long\n", len));
1092 rl = read(c, buf, len);
1096 DEBUG(0,("Unable to read from connection\n"));
1100 #ifdef DEBUG_PASSWORD
1101 dump_data(100, buf, rl);
1103 version = SVAL(p, 0);
1105 command = SVAL(p, 0);
1108 memcpy(con, p, sizeof(*con));
1111 DEBUG(10,("read_nmb_sock: ip %s port: %d\n",
1112 inet_ntoa(con->ip), con->port));
1114 if (PTR_DIFF(p, buf) != rl)
1116 DEBUG(0,("Buffer size %d %d!\n",
1117 PTR_DIFF(p, buf), rl));
1124 int get_nmb_sock(void)
1127 slprintf(path, sizeof(path)-1, "/tmp/.nmb/agent");
1129 return open_pipe_sock(path);