few edits
[Samba.git] / source / libsmb / nmblib.c
blob95d124c02087a98e7790689a24e9e421f601c8cf
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
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.
23 #include "includes.h"
25 int num_good_sends = 0;
26 int num_good_receives = 0;
28 static const struct opcode_names {
29 char *nmb_opcode_name;
30 int opcode;
31 } nmb_header_opcode_names[] = {
32 {"Query", 0 },
33 {"Registration", 5 },
34 {"Release", 6 },
35 {"WACK", 7 },
36 {"Refresh", 8 },
37 {"Refresh(altcode)", 9 },
38 {"Multi-homed Registration", 15 },
39 {0, -1 }
42 /****************************************************************************
43 * Lookup a nmb opcode name.
44 ****************************************************************************/
45 static const char *lookup_opcode_name( int opcode )
47 const struct opcode_names *op_namep;
48 int i;
50 for(i = 0; nmb_header_opcode_names[i].nmb_opcode_name != 0; i++) {
51 op_namep = &nmb_header_opcode_names[i];
52 if(opcode == op_namep->opcode)
53 return op_namep->nmb_opcode_name;
55 return "<unknown opcode>";
58 /****************************************************************************
59 print out a res_rec structure
60 ****************************************************************************/
61 static void debug_nmb_res_rec(struct res_rec *res, char *hdr)
63 int i, j;
65 DEBUGADD( 4, ( " %s: nmb_name=%s rr_type=%d rr_class=%d ttl=%d\n",
66 hdr,
67 nmb_namestr(&res->rr_name),
68 res->rr_type,
69 res->rr_class,
70 res->ttl ) );
72 if( res->rdlength == 0 || res->rdata == NULL )
73 return;
75 for (i = 0; i < res->rdlength; i+= 16)
77 DEBUGADD(4, (" %s %3x char ", hdr, i));
79 for (j = 0; j < 16; j++)
81 uchar x = res->rdata[i+j];
82 if (x < 32 || x > 127) x = '.';
84 if (i+j >= res->rdlength) break;
85 DEBUGADD(4, ("%c", x));
88 DEBUGADD(4, (" hex "));
90 for (j = 0; j < 16; j++)
92 if (i+j >= res->rdlength) break;
93 DEBUGADD(4, ("%02X", (uchar)res->rdata[i+j]));
96 DEBUGADD(4, ("\n"));
100 /****************************************************************************
101 process a nmb packet
102 ****************************************************************************/
103 void debug_nmb_packet(struct packet_struct *p)
105 struct nmb_packet *nmb = &p->packet.nmb;
107 if( DEBUGLVL( 4 ) )
109 dbgtext( "nmb packet from %s(%d) header: id=%d opcode=%s(%d) response=%s\n",
110 inet_ntoa(p->ip), p->port,
111 nmb->header.name_trn_id,
112 lookup_opcode_name(nmb->header.opcode),
113 nmb->header.opcode,
114 BOOLSTR(nmb->header.response) );
115 dbgtext( " header: flags: bcast=%s rec_avail=%s rec_des=%s trunc=%s auth=%s\n",
116 BOOLSTR(nmb->header.nm_flags.bcast),
117 BOOLSTR(nmb->header.nm_flags.recursion_available),
118 BOOLSTR(nmb->header.nm_flags.recursion_desired),
119 BOOLSTR(nmb->header.nm_flags.trunc),
120 BOOLSTR(nmb->header.nm_flags.authoritative) );
121 dbgtext( " header: rcode=%d qdcount=%d ancount=%d nscount=%d arcount=%d\n",
122 nmb->header.rcode,
123 nmb->header.qdcount,
124 nmb->header.ancount,
125 nmb->header.nscount,
126 nmb->header.arcount );
129 if (nmb->header.qdcount)
131 DEBUGADD( 4, ( " question: q_name=%s q_type=%d q_class=%d\n",
132 nmb_namestr(&nmb->question.question_name),
133 nmb->question.question_type,
134 nmb->question.question_class) );
137 if (nmb->answers && nmb->header.ancount)
139 debug_nmb_res_rec(nmb->answers,"answers");
141 if (nmb->nsrecs && nmb->header.nscount)
143 debug_nmb_res_rec(nmb->nsrecs,"nsrecs");
145 if (nmb->additional && nmb->header.arcount)
147 debug_nmb_res_rec(nmb->additional,"additional");
151 /*******************************************************************
152 handle "compressed" name pointers
153 ******************************************************************/
154 static BOOL handle_name_ptrs(uchar *ubuf,int *offset,int length,
155 BOOL *got_pointer,int *ret)
157 int loop_count=0;
159 while ((ubuf[*offset] & 0xC0) == 0xC0) {
160 if (!*got_pointer) (*ret) += 2;
161 (*got_pointer)=True;
162 (*offset) = ((ubuf[*offset] & ~0xC0)<<8) | ubuf[(*offset)+1];
163 if (loop_count++ == 10 || (*offset) < 0 || (*offset)>(length-2)) {
164 return(False);
167 return(True);
170 /*******************************************************************
171 parse a nmb name from "compressed" format to something readable
172 return the space taken by the name, or 0 if the name is invalid
173 ******************************************************************/
174 static int parse_nmb_name(char *inbuf,int ofs,int length, struct nmb_name *name)
176 int m,n=0;
177 uchar *ubuf = (uchar *)inbuf;
178 int ret = 0;
179 BOOL got_pointer=False;
180 int loop_count=0;
181 int offset = ofs;
183 if (length - offset < 2)
184 return(0);
186 /* handle initial name pointers */
187 if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret))
188 return(0);
190 m = ubuf[offset];
192 if (!m)
193 return(0);
194 if ((m & 0xC0) || offset+m+2 > length)
195 return(0);
197 memset((char *)name,'\0',sizeof(*name));
199 /* the "compressed" part */
200 if (!got_pointer)
201 ret += m + 2;
202 offset++;
203 while (m > 0) {
204 uchar c1,c2;
205 c1 = ubuf[offset++]-'A';
206 c2 = ubuf[offset++]-'A';
207 if ((c1 & 0xF0) || (c2 & 0xF0) || (n > sizeof(name->name)-1))
208 return(0);
209 name->name[n++] = (c1<<4) | c2;
210 m -= 2;
212 name->name[n] = 0;
214 if (n==16) {
215 /* parse out the name type,
216 its always in the 16th byte of the name */
217 name->name_type = ((uchar)name->name[15]) & 0xff;
219 /* remove trailing spaces */
220 name->name[15] = 0;
221 n = 14;
222 while (n && name->name[n]==' ')
223 name->name[n--] = 0;
226 /* now the domain parts (if any) */
227 n = 0;
228 while (ubuf[offset]) {
229 /* we can have pointers within the domain part as well */
230 if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret))
231 return(0);
233 m = ubuf[offset];
235 * Don't allow null domain parts.
237 if (!m)
238 return(0);
239 if (!got_pointer)
240 ret += m+1;
241 if (n)
242 name->scope[n++] = '.';
243 if (m+2+offset>length || n+m+1>sizeof(name->scope))
244 return(0);
245 offset++;
246 while (m--)
247 name->scope[n++] = (char)ubuf[offset++];
250 * Watch for malicious loops.
252 if (loop_count++ == 10)
253 return 0;
255 name->scope[n++] = 0;
257 return(ret);
261 /*******************************************************************
262 put a compressed nmb name into a buffer. return the length of the
263 compressed name
265 compressed names are really weird. The "compression" doubles the
266 size. The idea is that it also means that compressed names conform
267 to the doman name system. See RFC1002.
268 ******************************************************************/
269 static int put_nmb_name(char *buf,int offset,struct nmb_name *name)
271 int ret,m;
272 fstring buf1;
273 char *p;
275 if (strcmp(name->name,"*") == 0) {
276 /* special case for wildcard name */
277 memset(buf1,'\0',20);
278 buf1[0] = '*';
279 buf1[15] = name->name_type;
280 } else {
281 slprintf(buf1, sizeof(buf1) - 1,"%-15.15s%c",name->name,name->name_type);
284 buf[offset] = 0x20;
286 ret = 34;
288 for (m=0;m<16;m++) {
289 buf[offset+1+2*m] = 'A' + ((buf1[m]>>4)&0xF);
290 buf[offset+2+2*m] = 'A' + (buf1[m]&0xF);
292 offset += 33;
294 buf[offset] = 0;
296 if (name->scope[0]) {
297 /* XXXX this scope handling needs testing */
298 ret += strlen(name->scope) + 1;
299 pstrcpy(&buf[offset+1],name->scope);
301 p = &buf[offset+1];
302 while ((p = strchr(p,'.'))) {
303 buf[offset] = PTR_DIFF(p,&buf[offset+1]);
304 offset += (buf[offset] + 1);
305 p = &buf[offset+1];
307 buf[offset] = strlen(&buf[offset+1]);
310 return(ret);
313 /*******************************************************************
314 useful for debugging messages
315 ******************************************************************/
316 char *nmb_namestr(struct nmb_name *n)
318 static int i=0;
319 static fstring ret[4];
320 char *p = ret[i];
322 if (!n->scope[0])
323 slprintf(p,sizeof(fstring)-1, "%s<%02x>",n->name,n->name_type);
324 else
325 slprintf(p,sizeof(fstring)-1, "%s<%02x>.%s",n->name,n->name_type,n->scope);
327 i = (i+1)%4;
328 return(p);
331 /*******************************************************************
332 allocate and parse some resource records
333 ******************************************************************/
334 static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length,
335 struct res_rec **recs, int count)
337 int i;
338 *recs = (struct res_rec *)malloc(sizeof(**recs)*count);
339 if (!*recs) return(False);
341 memset((char *)*recs,'\0',sizeof(**recs)*count);
343 for (i=0;i<count;i++) {
344 int l = parse_nmb_name(inbuf,*offset,length,&(*recs)[i].rr_name);
345 (*offset) += l;
346 if (!l || (*offset)+10 > length) {
347 SAFE_FREE(*recs);
348 return(False);
350 (*recs)[i].rr_type = RSVAL(inbuf,(*offset));
351 (*recs)[i].rr_class = RSVAL(inbuf,(*offset)+2);
352 (*recs)[i].ttl = RIVAL(inbuf,(*offset)+4);
353 (*recs)[i].rdlength = RSVAL(inbuf,(*offset)+8);
354 (*offset) += 10;
355 if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) ||
356 (*offset)+(*recs)[i].rdlength > length) {
357 SAFE_FREE(*recs);
358 return(False);
360 memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength);
361 (*offset) += (*recs)[i].rdlength;
363 return(True);
366 /*******************************************************************
367 put a resource record into a packet
368 ******************************************************************/
369 static int put_res_rec(char *buf,int offset,struct res_rec *recs,int count)
371 int ret=0;
372 int i;
374 for (i=0;i<count;i++) {
375 int l = put_nmb_name(buf,offset,&recs[i].rr_name);
376 offset += l;
377 ret += l;
378 RSSVAL(buf,offset,recs[i].rr_type);
379 RSSVAL(buf,offset+2,recs[i].rr_class);
380 RSIVAL(buf,offset+4,recs[i].ttl);
381 RSSVAL(buf,offset+8,recs[i].rdlength);
382 memcpy(buf+offset+10,recs[i].rdata,recs[i].rdlength);
383 offset += 10+recs[i].rdlength;
384 ret += 10+recs[i].rdlength;
387 return(ret);
390 /*******************************************************************
391 put a compressed name pointer record into a packet
392 ******************************************************************/
393 static int put_compressed_name_ptr(uchar *buf,int offset,struct res_rec *rec,int ptr_offset)
395 int ret=0;
396 buf[offset] = (0xC0 | ((ptr_offset >> 8) & 0xFF));
397 buf[offset+1] = (ptr_offset & 0xFF);
398 offset += 2;
399 ret += 2;
400 RSSVAL(buf,offset,rec->rr_type);
401 RSSVAL(buf,offset+2,rec->rr_class);
402 RSIVAL(buf,offset+4,rec->ttl);
403 RSSVAL(buf,offset+8,rec->rdlength);
404 memcpy(buf+offset+10,rec->rdata,rec->rdlength);
405 offset += 10+rec->rdlength;
406 ret += 10+rec->rdlength;
408 return(ret);
411 /*******************************************************************
412 parse a dgram packet. Return False if the packet can't be parsed
413 or is invalid for some reason, True otherwise
415 this is documented in section 4.4.1 of RFC1002
416 ******************************************************************/
417 static BOOL parse_dgram(char *inbuf,int length,struct dgram_packet *dgram)
419 int offset;
420 int flags;
422 memset((char *)dgram,'\0',sizeof(*dgram));
424 if (length < 14) return(False);
426 dgram->header.msg_type = CVAL(inbuf,0);
427 flags = CVAL(inbuf,1);
428 dgram->header.flags.node_type = (enum node_type)((flags>>2)&3);
429 if (flags & 1) dgram->header.flags.more = True;
430 if (flags & 2) dgram->header.flags.first = True;
431 dgram->header.dgm_id = RSVAL(inbuf,2);
432 putip((char *)&dgram->header.source_ip,inbuf+4);
433 dgram->header.source_port = RSVAL(inbuf,8);
434 dgram->header.dgm_length = RSVAL(inbuf,10);
435 dgram->header.packet_offset = RSVAL(inbuf,12);
437 offset = 14;
439 if (dgram->header.msg_type == 0x10 ||
440 dgram->header.msg_type == 0x11 ||
441 dgram->header.msg_type == 0x12) {
442 offset += parse_nmb_name(inbuf,offset,length,&dgram->source_name);
443 offset += parse_nmb_name(inbuf,offset,length,&dgram->dest_name);
446 if (offset >= length || (length-offset > sizeof(dgram->data)))
447 return(False);
449 dgram->datasize = length-offset;
450 memcpy(dgram->data,inbuf+offset,dgram->datasize);
452 return(True);
456 /*******************************************************************
457 parse a nmb packet. Return False if the packet can't be parsed
458 or is invalid for some reason, True otherwise
459 ******************************************************************/
460 static BOOL parse_nmb(char *inbuf,int length,struct nmb_packet *nmb)
462 int nm_flags,offset;
464 memset((char *)nmb,'\0',sizeof(*nmb));
466 if (length < 12) return(False);
468 /* parse the header */
469 nmb->header.name_trn_id = RSVAL(inbuf,0);
471 DEBUG(10,("parse_nmb: packet id = %d\n", nmb->header.name_trn_id));
473 nmb->header.opcode = (CVAL(inbuf,2) >> 3) & 0xF;
474 nmb->header.response = ((CVAL(inbuf,2)>>7)&1)?True:False;
475 nm_flags = ((CVAL(inbuf,2) & 0x7) << 4) + (CVAL(inbuf,3)>>4);
476 nmb->header.nm_flags.bcast = (nm_flags&1)?True:False;
477 nmb->header.nm_flags.recursion_available = (nm_flags&8)?True:False;
478 nmb->header.nm_flags.recursion_desired = (nm_flags&0x10)?True:False;
479 nmb->header.nm_flags.trunc = (nm_flags&0x20)?True:False;
480 nmb->header.nm_flags.authoritative = (nm_flags&0x40)?True:False;
481 nmb->header.rcode = CVAL(inbuf,3) & 0xF;
482 nmb->header.qdcount = RSVAL(inbuf,4);
483 nmb->header.ancount = RSVAL(inbuf,6);
484 nmb->header.nscount = RSVAL(inbuf,8);
485 nmb->header.arcount = RSVAL(inbuf,10);
487 if (nmb->header.qdcount) {
488 offset = parse_nmb_name(inbuf,12,length,&nmb->question.question_name);
489 if (!offset) return(False);
491 if (length - (12+offset) < 4) return(False);
492 nmb->question.question_type = RSVAL(inbuf,12+offset);
493 nmb->question.question_class = RSVAL(inbuf,12+offset+2);
495 offset += 12+4;
496 } else {
497 offset = 12;
500 /* and any resource records */
501 if (nmb->header.ancount &&
502 !parse_alloc_res_rec(inbuf,&offset,length,&nmb->answers,
503 nmb->header.ancount))
504 return(False);
506 if (nmb->header.nscount &&
507 !parse_alloc_res_rec(inbuf,&offset,length,&nmb->nsrecs,
508 nmb->header.nscount))
509 return(False);
511 if (nmb->header.arcount &&
512 !parse_alloc_res_rec(inbuf,&offset,length,&nmb->additional,
513 nmb->header.arcount))
514 return(False);
516 return(True);
519 /*******************************************************************
520 'Copy constructor' for an nmb packet
521 ******************************************************************/
522 static struct packet_struct *copy_nmb_packet(struct packet_struct *packet)
524 struct nmb_packet *nmb;
525 struct nmb_packet *copy_nmb;
526 struct packet_struct *pkt_copy;
528 if(( pkt_copy = (struct packet_struct *)malloc(sizeof(*packet))) == NULL)
530 DEBUG(0,("copy_nmb_packet: malloc fail.\n"));
531 return NULL;
534 /* Structure copy of entire thing. */
536 *pkt_copy = *packet;
538 /* Ensure this copy is not locked. */
539 pkt_copy->locked = False;
541 /* Ensure this copy has no resource records. */
542 nmb = &packet->packet.nmb;
543 copy_nmb = &pkt_copy->packet.nmb;
545 copy_nmb->answers = NULL;
546 copy_nmb->nsrecs = NULL;
547 copy_nmb->additional = NULL;
549 /* Now copy any resource records. */
551 if (nmb->answers)
553 if((copy_nmb->answers = (struct res_rec *)
554 malloc(nmb->header.ancount * sizeof(struct res_rec))) == NULL)
555 goto free_and_exit;
556 memcpy((char *)copy_nmb->answers, (char *)nmb->answers,
557 nmb->header.ancount * sizeof(struct res_rec));
559 if (nmb->nsrecs)
561 if((copy_nmb->nsrecs = (struct res_rec *)
562 malloc(nmb->header.nscount * sizeof(struct res_rec))) == NULL)
563 goto free_and_exit;
564 memcpy((char *)copy_nmb->nsrecs, (char *)nmb->nsrecs,
565 nmb->header.nscount * sizeof(struct res_rec));
567 if (nmb->additional)
569 if((copy_nmb->additional = (struct res_rec *)
570 malloc(nmb->header.arcount * sizeof(struct res_rec))) == NULL)
571 goto free_and_exit;
572 memcpy((char *)copy_nmb->additional, (char *)nmb->additional,
573 nmb->header.arcount * sizeof(struct res_rec));
576 return pkt_copy;
578 free_and_exit:
580 SAFE_FREE(copy_nmb->answers);
581 SAFE_FREE(copy_nmb->nsrecs);
582 SAFE_FREE(copy_nmb->additional);
583 SAFE_FREE(pkt_copy);
585 DEBUG(0,("copy_nmb_packet: malloc fail in resource records.\n"));
586 return NULL;
589 /*******************************************************************
590 'Copy constructor' for a dgram packet
591 ******************************************************************/
592 static struct packet_struct *copy_dgram_packet(struct packet_struct *packet)
594 struct packet_struct *pkt_copy;
596 if(( pkt_copy = (struct packet_struct *)malloc(sizeof(*packet))) == NULL)
598 DEBUG(0,("copy_dgram_packet: malloc fail.\n"));
599 return NULL;
602 /* Structure copy of entire thing. */
604 *pkt_copy = *packet;
606 /* Ensure this copy is not locked. */
607 pkt_copy->locked = False;
609 /* There are no additional pointers in a dgram packet,
610 we are finished. */
611 return pkt_copy;
614 /*******************************************************************
615 'Copy constructor' for a generic packet
616 ******************************************************************/
617 struct packet_struct *copy_packet(struct packet_struct *packet)
619 if(packet->packet_type == NMB_PACKET)
620 return copy_nmb_packet(packet);
621 else if (packet->packet_type == DGRAM_PACKET)
622 return copy_dgram_packet(packet);
623 return NULL;
626 /*******************************************************************
627 free up any resources associated with an nmb packet
628 ******************************************************************/
629 static void free_nmb_packet(struct nmb_packet *nmb)
631 SAFE_FREE(nmb->answers);
632 SAFE_FREE(nmb->nsrecs);
633 SAFE_FREE(nmb->additional);
636 /*******************************************************************
637 free up any resources associated with a dgram packet
638 ******************************************************************/
639 static void free_dgram_packet(struct dgram_packet *nmb)
641 /* We have nothing to do for a dgram packet. */
644 /*******************************************************************
645 free up any resources associated with a packet
646 ******************************************************************/
647 void free_packet(struct packet_struct *packet)
649 if (packet->locked)
650 return;
651 if (packet->packet_type == NMB_PACKET)
652 free_nmb_packet(&packet->packet.nmb);
653 else if (packet->packet_type == DGRAM_PACKET)
654 free_dgram_packet(&packet->packet.dgram);
655 ZERO_STRUCTPN(packet);
656 SAFE_FREE(packet);
659 /*******************************************************************
660 parse a packet buffer into a packet structure
661 ******************************************************************/
662 struct packet_struct *parse_packet(char *buf,int length,
663 enum packet_type packet_type)
665 extern struct in_addr lastip;
666 extern int lastport;
667 struct packet_struct *p;
668 BOOL ok=False;
670 p = (struct packet_struct *)malloc(sizeof(*p));
671 if (!p) return(NULL);
673 p->next = NULL;
674 p->prev = NULL;
675 p->ip = lastip;
676 p->port = lastport;
677 p->locked = False;
678 p->timestamp = time(NULL);
679 p->packet_type = packet_type;
681 switch (packet_type) {
682 case NMB_PACKET:
683 ok = parse_nmb(buf,length,&p->packet.nmb);
684 break;
686 case DGRAM_PACKET:
687 ok = parse_dgram(buf,length,&p->packet.dgram);
688 break;
691 if (!ok) {
692 free_packet(p);
693 return NULL;
696 return p;
699 /*******************************************************************
700 read a packet from a socket and parse it, returning a packet ready
701 to be used or put on the queue. This assumes a UDP socket
702 ******************************************************************/
703 struct packet_struct *read_packet(int fd,enum packet_type packet_type)
705 struct packet_struct *packet;
706 char buf[MAX_DGRAM_SIZE];
707 int length;
709 length = read_udp_socket(fd,buf,sizeof(buf));
710 if (length < MIN_DGRAM_SIZE) return(NULL);
712 packet = parse_packet(buf, length, packet_type);
713 if (!packet) return NULL;
715 packet->fd = fd;
717 num_good_receives++;
719 DEBUG(5,("Received a packet of len %d from (%s) port %d\n",
720 length, inet_ntoa(packet->ip), packet->port ) );
722 return(packet);
726 /*******************************************************************
727 send a udp packet on a already open socket
728 ******************************************************************/
729 static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port)
731 BOOL ret = False;
732 int i;
733 struct sockaddr_in sock_out;
735 /* set the address and port */
736 memset((char *)&sock_out,'\0',sizeof(sock_out));
737 putip((char *)&sock_out.sin_addr,(char *)&ip);
738 sock_out.sin_port = htons( port );
739 sock_out.sin_family = AF_INET;
741 DEBUG( 5, ( "Sending a packet of len %d to (%s) on port %d\n",
742 len, inet_ntoa(ip), port ) );
745 * Patch to fix asynch error notifications from Linux kernel.
748 for (i = 0; i < 5; i++) {
749 ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out, sizeof(sock_out)) >= 0);
750 if (ret || errno != ECONNREFUSED)
751 break;
754 if (!ret)
755 DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n",
756 inet_ntoa(ip),port,strerror(errno)));
758 if (ret)
759 num_good_sends++;
761 return(ret);
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.
771 [...but it isn't clear that we would ever need to send a
772 a fragmented NBT Datagram. The IP layer does its own
773 fragmentation to ensure that messages can fit into the path
774 MTU. It *is* important to be able to receive and rebuild
775 fragmented NBT datagrams, just in case someone out there
776 really has implemented this 'feature'. crh -)------ ]
778 ******************************************************************/
779 static int build_dgram(char *buf,struct packet_struct *p)
781 struct dgram_packet *dgram = &p->packet.dgram;
782 uchar *ubuf = (uchar *)buf;
783 int offset=0;
785 /* put in the header */
786 ubuf[0] = dgram->header.msg_type;
787 ubuf[1] = (((int)dgram->header.flags.node_type)<<2);
788 if (dgram->header.flags.more)
789 ubuf[1] |= 1;
790 if (dgram->header.flags.first)
791 ubuf[1] |= 2;
792 RSSVAL(ubuf,2,dgram->header.dgm_id);
793 putip(ubuf+4,(char *)&dgram->header.source_ip);
794 RSSVAL(ubuf,8,dgram->header.source_port);
795 RSSVAL(ubuf,12,dgram->header.packet_offset);
797 offset = 14;
799 if (dgram->header.msg_type == 0x10 ||
800 dgram->header.msg_type == 0x11 ||
801 dgram->header.msg_type == 0x12) {
802 offset += put_nmb_name((char *)ubuf,offset,&dgram->source_name);
803 offset += put_nmb_name((char *)ubuf,offset,&dgram->dest_name);
806 memcpy(ubuf+offset,dgram->data,dgram->datasize);
807 offset += dgram->datasize;
809 /* automatically set the dgm_length
810 * NOTE: RFC1002 says the dgm_length does *not*
811 * include the fourteen-byte header. crh
813 dgram->header.dgm_length = (offset - 14);
814 RSSVAL(ubuf,10,dgram->header.dgm_length);
816 return(offset);
819 /*******************************************************************
820 build a nmb name
821 *******************************************************************/
822 void make_nmb_name( struct nmb_name *n, const char *name, int type)
824 extern pstring global_scope;
825 memset( (char *)n, '\0', sizeof(struct nmb_name) );
826 StrnCpy( n->name, name, 15 );
827 unix_to_dos(n->name);
828 strupper( n->name );
829 n->name_type = (unsigned int)type & 0xFF;
830 StrnCpy( n->scope, global_scope, 63 );
831 strupper( n->scope );
834 /*******************************************************************
835 Compare two nmb names
836 ******************************************************************/
838 BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2)
840 return ((n1->name_type == n2->name_type) &&
841 strequal(n1->name ,n2->name ) &&
842 strequal(n1->scope,n2->scope));
845 /*******************************************************************
846 build a nmb packet ready for sending
848 XXXX this currently relies on not being passed something that expands
849 to a packet too big for the buffer. Eventually this should be
850 changed to set the trunc bit so the receiver can request the rest
851 via tcp (when that becomes supported)
852 ******************************************************************/
853 static int build_nmb(char *buf,struct packet_struct *p)
855 struct nmb_packet *nmb = &p->packet.nmb;
856 uchar *ubuf = (uchar *)buf;
857 int offset=0;
859 /* put in the header */
860 RSSVAL(ubuf,offset,nmb->header.name_trn_id);
861 ubuf[offset+2] = (nmb->header.opcode & 0xF) << 3;
862 if (nmb->header.response) ubuf[offset+2] |= (1<<7);
863 if (nmb->header.nm_flags.authoritative &&
864 nmb->header.response) ubuf[offset+2] |= 0x4;
865 if (nmb->header.nm_flags.trunc) ubuf[offset+2] |= 0x2;
866 if (nmb->header.nm_flags.recursion_desired) ubuf[offset+2] |= 0x1;
867 if (nmb->header.nm_flags.recursion_available &&
868 nmb->header.response) ubuf[offset+3] |= 0x80;
869 if (nmb->header.nm_flags.bcast) ubuf[offset+3] |= 0x10;
870 ubuf[offset+3] |= (nmb->header.rcode & 0xF);
872 RSSVAL(ubuf,offset+4,nmb->header.qdcount);
873 RSSVAL(ubuf,offset+6,nmb->header.ancount);
874 RSSVAL(ubuf,offset+8,nmb->header.nscount);
875 RSSVAL(ubuf,offset+10,nmb->header.arcount);
877 offset += 12;
878 if (nmb->header.qdcount) {
879 /* XXXX this doesn't handle a qdcount of > 1 */
880 offset += put_nmb_name((char *)ubuf,offset,&nmb->question.question_name);
881 RSSVAL(ubuf,offset,nmb->question.question_type);
882 RSSVAL(ubuf,offset+2,nmb->question.question_class);
883 offset += 4;
886 if (nmb->header.ancount)
887 offset += put_res_rec((char *)ubuf,offset,nmb->answers,
888 nmb->header.ancount);
890 if (nmb->header.nscount)
891 offset += put_res_rec((char *)ubuf,offset,nmb->nsrecs,
892 nmb->header.nscount);
895 * The spec says we must put compressed name pointers
896 * in the following outgoing packets :
897 * NAME_REGISTRATION_REQUEST, NAME_REFRESH_REQUEST,
898 * NAME_RELEASE_REQUEST.
901 if((nmb->header.response == False) &&
902 ((nmb->header.opcode == NMB_NAME_REG_OPCODE) ||
903 (nmb->header.opcode == NMB_NAME_RELEASE_OPCODE) ||
904 (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_8) ||
905 (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_9) ||
906 (nmb->header.opcode == NMB_NAME_MULTIHOMED_REG_OPCODE)) &&
907 (nmb->header.arcount == 1)) {
909 offset += put_compressed_name_ptr(ubuf,offset,nmb->additional,12);
911 } else if (nmb->header.arcount) {
912 offset += put_res_rec((char *)ubuf,offset,nmb->additional,
913 nmb->header.arcount);
915 return(offset);
919 /*******************************************************************
920 linearise a packet
921 ******************************************************************/
922 int build_packet(char *buf, struct packet_struct *p)
924 int len = 0;
926 switch (p->packet_type) {
927 case NMB_PACKET:
928 len = build_nmb(buf,p);
929 break;
931 case DGRAM_PACKET:
932 len = build_dgram(buf,p);
933 break;
936 return len;
939 /*******************************************************************
940 send a packet_struct
941 ******************************************************************/
942 BOOL send_packet(struct packet_struct *p)
944 char buf[1024];
945 int len=0;
947 memset(buf,'\0',sizeof(buf));
949 len = build_packet(buf, p);
951 if (!len) return(False);
953 return(send_udp(p->fd,buf,len,p->ip,p->port));
956 /****************************************************************************
957 receive a packet with timeout on a open UDP filedescriptor
958 The timeout is in milliseconds
959 ***************************************************************************/
960 struct packet_struct *receive_packet(int fd,enum packet_type type,int t)
962 fd_set fds;
963 struct timeval timeout;
964 int ret;
966 FD_ZERO(&fds);
967 FD_SET(fd,&fds);
968 timeout.tv_sec = t/1000;
969 timeout.tv_usec = 1000*(t%1000);
971 if ((ret = sys_select_intr(fd+1,&fds,NULL,NULL,&timeout)) == -1) {
972 /* errno should be EBADF or EINVAL. */
973 DEBUG(0,("select returned -1, errno = %s (%d)\n", strerror(errno), errno));
974 return NULL;
977 if (ret == 0) /* timeout */
978 return NULL;
980 if (FD_ISSET(fd,&fds))
981 return(read_packet(fd,type));
983 return(NULL);
987 /****************************************************************************
988 receive a UDP/137 packet either via UDP or from the unexpected packet
989 queue. The packet must be a reply packet and have the specified trn_id
990 The timeout is in milliseconds
991 ***************************************************************************/
992 struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id)
994 struct packet_struct *p;
996 p = receive_packet(fd, NMB_PACKET, t);
998 if (p && p->packet.nmb.header.response &&
999 p->packet.nmb.header.name_trn_id == trn_id) {
1000 return p;
1002 if (p) free_packet(p);
1004 /* try the unexpected packet queue */
1005 return receive_unexpected(NMB_PACKET, trn_id, NULL);
1008 /****************************************************************************
1009 receive a UDP/138 packet either via UDP or from the unexpected packet
1010 queue. The packet must be a reply packet and have the specified mailslot name
1011 The timeout is in milliseconds
1012 ***************************************************************************/
1013 struct packet_struct *receive_dgram_packet(int fd, int t, char *mailslot_name)
1015 struct packet_struct *p;
1017 p = receive_packet(fd, DGRAM_PACKET, t);
1019 if (p && match_mailslot_name(p, mailslot_name)) {
1020 return p;
1022 if (p) free_packet(p);
1024 /* try the unexpected packet queue */
1025 return receive_unexpected(DGRAM_PACKET, 0, mailslot_name);
1029 /****************************************************************************
1030 see if a datagram has the right mailslot name
1031 ***************************************************************************/
1032 BOOL match_mailslot_name(struct packet_struct *p, char *mailslot_name)
1034 struct dgram_packet *dgram = &p->packet.dgram;
1035 char *buf;
1037 buf = &dgram->data[0];
1038 buf -= 4;
1040 buf = smb_buf(buf);
1042 if (memcmp(buf, mailslot_name, strlen(mailslot_name)+1) == 0) {
1043 return True;
1046 return False;
1050 /****************************************************************************
1051 return the number of bits that match between two 4 character buffers
1052 ***************************************************************************/
1053 static int matching_bits(uchar *p1, uchar *p2)
1055 int i, j, ret = 0;
1056 for (i=0; i<4; i++) {
1057 if (p1[i] != p2[i]) break;
1058 ret += 8;
1061 if (i==4) return ret;
1063 for (j=0; j<8; j++) {
1064 if ((p1[i] & (1<<(7-j))) != (p2[i] & (1<<(7-j)))) break;
1065 ret++;
1068 return ret;
1072 static uchar sort_ip[4];
1074 /****************************************************************************
1075 compare two query reply records
1076 ***************************************************************************/
1077 static int name_query_comp(uchar *p1, uchar *p2)
1079 return matching_bits(p2+2, sort_ip) - matching_bits(p1+2, sort_ip);
1082 /****************************************************************************
1083 sort a set of 6 byte name query response records so that the IPs that
1084 have the most leading bits in common with the specified address come first
1085 ***************************************************************************/
1086 void sort_query_replies(char *data, int n, struct in_addr ip)
1088 if (n <= 1) return;
1090 putip(sort_ip, (char *)&ip);
1092 qsort(data, n, 6, QSORT_CAST name_query_comp);
1096 #define TRUNCATE_NETBIOS_NAME 1
1098 /*******************************************************************
1099 convert, possibly using a stupid microsoft-ism which has destroyed
1100 the transport independence of netbios (for CIFS vendors that usually
1101 use the Win95-type methods, not for NT to NT communication, which uses
1102 DCE/RPC and therefore full-length unicode strings...) a dns name into
1103 a netbios name.
1105 the netbios name (NOT necessarily null-terminated) is truncated to 15
1106 characters.
1108 ******************************************************************/
1109 char *dns_to_netbios_name(char *dns_name)
1111 static char netbios_name[16];
1112 int i;
1113 StrnCpy(netbios_name, dns_name, 15);
1114 netbios_name[15] = 0;
1116 #ifdef TRUNCATE_NETBIOS_NAME
1117 /* ok. this is because of a stupid microsoft-ism. if the called host
1118 name contains a '.', microsoft clients expect you to truncate the
1119 netbios name up to and including the '.' this even applies, by
1120 mistake, to workgroup (domain) names, which is _really_ daft.
1123 * We need to go up, not down, to avoid netbios names like
1124 * fred.xyz being produced from fred.xyz.someco.com.
1126 for (i = 0; i < 15; i++)
1128 if (netbios_name[i] == '.')
1130 netbios_name[i] = 0;
1131 break;
1134 #endif /* TRUNCATE_NETBIOS_NAME */
1136 return netbios_name;
1140 /****************************************************************************
1141 interpret the weird netbios "name". Return the name type
1142 ****************************************************************************/
1143 static int name_interpret(char *in,char *out)
1145 int ret;
1146 int len = (*in++) / 2;
1148 *out=0;
1150 if (len > 30 || len<1) return(0);
1152 while (len--)
1154 if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
1155 *out = 0;
1156 return(0);
1158 *out = ((in[0]-'A')<<4) + (in[1]-'A');
1159 in += 2;
1160 out++;
1162 *out = 0;
1163 ret = out[-1];
1165 #ifdef NETBIOS_SCOPE
1166 /* Handle any scope names */
1167 while(*in)
1169 *out++ = '.'; /* Scope names are separated by periods */
1170 len = *(uchar *)in++;
1171 StrnCpy(out, in, len);
1172 out += len;
1173 *out=0;
1174 in += len;
1176 #endif
1177 return(ret);
1180 /****************************************************************************
1181 mangle a name into netbios format
1183 Note: <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
1184 ****************************************************************************/
1185 int name_mangle( char *In, char *Out, char name_type )
1187 int i;
1188 int c;
1189 int len;
1190 char buf[20];
1191 char *p = Out;
1192 extern pstring global_scope;
1194 /* Safely copy the input string, In, into buf[]. */
1195 (void)memset( buf, 0, 20 );
1196 if (strcmp(In,"*") == 0)
1197 buf[0] = '*';
1198 else
1199 (void)slprintf( buf, sizeof(buf) - 1, "%-15.15s%c", In, name_type );
1201 /* Place the length of the first field into the output buffer. */
1202 p[0] = 32;
1203 p++;
1205 /* Now convert the name to the rfc1001/1002 format. */
1206 for( i = 0; i < 16; i++ )
1208 c = toupper( buf[i] );
1209 p[i*2] = ( (c >> 4) & 0x000F ) + 'A';
1210 p[(i*2)+1] = (c & 0x000F) + 'A';
1212 p += 32;
1213 p[0] = '\0';
1215 /* Add the scope string. */
1216 for( i = 0, len = 0; NULL != global_scope; i++, len++ )
1218 switch( global_scope[i] )
1220 case '\0':
1221 p[0] = len;
1222 if( len > 0 )
1223 p[len+1] = 0;
1224 return( name_len(Out) );
1225 case '.':
1226 p[0] = len;
1227 p += (len + 1);
1228 len = -1;
1229 break;
1230 default:
1231 p[len+1] = global_scope[i];
1232 break;
1236 return( name_len(Out) );
1237 } /* name_mangle */
1240 /****************************************************************************
1241 find a pointer to a netbios name
1242 ****************************************************************************/
1243 static char *name_ptr(char *buf,int ofs)
1245 uchar c = *(uchar *)(buf+ofs);
1247 if ((c & 0xC0) == 0xC0)
1249 uint16 l = RSVAL(buf, ofs) & 0x3FFF;
1250 DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
1251 return(buf + l);
1253 else
1254 return(buf+ofs);
1257 /****************************************************************************
1258 extract a netbios name from a buf
1259 ****************************************************************************/
1260 int name_extract(char *buf,int ofs,char *name)
1262 char *p = name_ptr(buf,ofs);
1263 int d = PTR_DIFF(p,buf+ofs);
1264 pstrcpy(name,"");
1265 if (d < -50 || d > 50) return(0);
1266 return(name_interpret(p,name));
1269 /****************************************************************************
1270 return the total storage length of a mangled name
1271 ****************************************************************************/
1272 int name_len(char *s1)
1274 /* NOTE: this argument _must_ be unsigned */
1275 uchar *s = (uchar *)s1;
1276 int len;
1278 /* If the two high bits of the byte are set, return 2. */
1279 if (0xC0 == (*s & 0xC0))
1280 return(2);
1282 /* Add up the length bytes. */
1283 for (len = 1; (*s); s += (*s) + 1) {
1284 len += *s + 1;
1285 SMB_ASSERT(len < 80);
1288 return(len);
1289 } /* name_len */