Fix up a bunch of compiler warnings ...
[Samba/vl.git] / source / libsmb / nmblib.c
blob30ce5b6b10c5aad29bec29a7acb40508d9c4bd8e
1 /*
2 Unix SMB/CIFS implementation.
3 NBT netbios library routines
4 Copyright (C) Andrew Tridgell 1994-1998
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "includes.h"
24 int num_good_sends = 0;
25 int num_good_receives = 0;
27 static const struct opcode_names {
28 const char *nmb_opcode_name;
29 int opcode;
30 } nmb_header_opcode_names[] = {
31 {"Query", 0 },
32 {"Registration", 5 },
33 {"Release", 6 },
34 {"WACK", 7 },
35 {"Refresh", 8 },
36 {"Refresh(altcode)", 9 },
37 {"Multi-homed Registration", 15 },
38 {0, -1 }
41 /****************************************************************************
42 * Lookup a nmb opcode name.
43 ****************************************************************************/
44 static const char *lookup_opcode_name( int opcode )
46 const struct opcode_names *op_namep;
47 int i;
49 for(i = 0; nmb_header_opcode_names[i].nmb_opcode_name != 0; i++) {
50 op_namep = &nmb_header_opcode_names[i];
51 if(opcode == op_namep->opcode)
52 return op_namep->nmb_opcode_name;
54 return "<unknown opcode>";
57 /****************************************************************************
58 print out a res_rec structure
59 ****************************************************************************/
60 static void debug_nmb_res_rec(struct res_rec *res, const char *hdr)
62 int i, j;
64 DEBUGADD( 4, ( " %s: nmb_name=%s rr_type=%d rr_class=%d ttl=%d\n",
65 hdr,
66 nmb_namestr(&res->rr_name),
67 res->rr_type,
68 res->rr_class,
69 res->ttl ) );
71 if( res->rdlength == 0 || res->rdata == NULL )
72 return;
74 for (i = 0; i < res->rdlength; i+= 16)
76 DEBUGADD(4, (" %s %3x char ", hdr, i));
78 for (j = 0; j < 16; j++)
80 uchar x = res->rdata[i+j];
81 if (x < 32 || x > 127) x = '.';
83 if (i+j >= res->rdlength) break;
84 DEBUGADD(4, ("%c", x));
87 DEBUGADD(4, (" hex "));
89 for (j = 0; j < 16; j++)
91 if (i+j >= res->rdlength) break;
92 DEBUGADD(4, ("%02X", (uchar)res->rdata[i+j]));
95 DEBUGADD(4, ("\n"));
99 /****************************************************************************
100 process a nmb packet
101 ****************************************************************************/
102 void debug_nmb_packet(struct packet_struct *p)
104 struct nmb_packet *nmb = &p->packet.nmb;
106 if( DEBUGLVL( 4 ) )
108 dbgtext( "nmb packet from %s(%d) header: id=%d opcode=%s(%d) response=%s\n",
109 inet_ntoa(p->ip), p->port,
110 nmb->header.name_trn_id,
111 lookup_opcode_name(nmb->header.opcode),
112 nmb->header.opcode,
113 BOOLSTR(nmb->header.response) );
114 dbgtext( " header: flags: bcast=%s rec_avail=%s rec_des=%s trunc=%s auth=%s\n",
115 BOOLSTR(nmb->header.nm_flags.bcast),
116 BOOLSTR(nmb->header.nm_flags.recursion_available),
117 BOOLSTR(nmb->header.nm_flags.recursion_desired),
118 BOOLSTR(nmb->header.nm_flags.trunc),
119 BOOLSTR(nmb->header.nm_flags.authoritative) );
120 dbgtext( " header: rcode=%d qdcount=%d ancount=%d nscount=%d arcount=%d\n",
121 nmb->header.rcode,
122 nmb->header.qdcount,
123 nmb->header.ancount,
124 nmb->header.nscount,
125 nmb->header.arcount );
128 if (nmb->header.qdcount)
130 DEBUGADD( 4, ( " question: q_name=%s q_type=%d q_class=%d\n",
131 nmb_namestr(&nmb->question.question_name),
132 nmb->question.question_type,
133 nmb->question.question_class) );
136 if (nmb->answers && nmb->header.ancount)
138 debug_nmb_res_rec(nmb->answers,"answers");
140 if (nmb->nsrecs && nmb->header.nscount)
142 debug_nmb_res_rec(nmb->nsrecs,"nsrecs");
144 if (nmb->additional && nmb->header.arcount)
146 debug_nmb_res_rec(nmb->additional,"additional");
150 /*******************************************************************
151 handle "compressed" name pointers
152 ******************************************************************/
153 static BOOL handle_name_ptrs(uchar *ubuf,int *offset,int length,
154 BOOL *got_pointer,int *ret)
156 int loop_count=0;
158 while ((ubuf[*offset] & 0xC0) == 0xC0) {
159 if (!*got_pointer) (*ret) += 2;
160 (*got_pointer)=True;
161 (*offset) = ((ubuf[*offset] & ~0xC0)<<8) | ubuf[(*offset)+1];
162 if (loop_count++ == 10 || (*offset) < 0 || (*offset)>(length-2)) {
163 return(False);
166 return(True);
169 /*******************************************************************
170 parse a nmb name from "compressed" format to something readable
171 return the space taken by the name, or 0 if the name is invalid
172 ******************************************************************/
173 static int parse_nmb_name(char *inbuf,int ofs,int length, struct nmb_name *name)
175 int m,n=0;
176 uchar *ubuf = (uchar *)inbuf;
177 int ret = 0;
178 BOOL got_pointer=False;
179 int loop_count=0;
180 int offset = ofs;
182 if (length - offset < 2)
183 return(0);
185 /* handle initial name pointers */
186 if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret))
187 return(0);
189 m = ubuf[offset];
191 if (!m)
192 return(0);
193 if ((m & 0xC0) || offset+m+2 > length)
194 return(0);
196 memset((char *)name,'\0',sizeof(*name));
198 /* the "compressed" part */
199 if (!got_pointer)
200 ret += m + 2;
201 offset++;
202 while (m > 0) {
203 uchar c1,c2;
204 c1 = ubuf[offset++]-'A';
205 c2 = ubuf[offset++]-'A';
206 if ((c1 & 0xF0) || (c2 & 0xF0) || (n > sizeof(name->name)-1))
207 return(0);
208 name->name[n++] = (c1<<4) | c2;
209 m -= 2;
211 name->name[n] = 0;
213 if (n==16) {
214 /* parse out the name type,
215 its always in the 16th byte of the name */
216 name->name_type = ((uchar)name->name[15]) & 0xff;
218 /* remove trailing spaces */
219 name->name[15] = 0;
220 n = 14;
221 while (n && name->name[n]==' ')
222 name->name[n--] = 0;
225 /* now the domain parts (if any) */
226 n = 0;
227 while (ubuf[offset]) {
228 /* we can have pointers within the domain part as well */
229 if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret))
230 return(0);
232 m = ubuf[offset];
234 * Don't allow null domain parts.
236 if (!m)
237 return(0);
238 if (!got_pointer)
239 ret += m+1;
240 if (n)
241 name->scope[n++] = '.';
242 if (m+2+offset>length || n+m+1>sizeof(name->scope))
243 return(0);
244 offset++;
245 while (m--)
246 name->scope[n++] = (char)ubuf[offset++];
249 * Watch for malicious loops.
251 if (loop_count++ == 10)
252 return 0;
254 name->scope[n++] = 0;
256 return(ret);
260 /*******************************************************************
261 put a compressed nmb name into a buffer. return the length of the
262 compressed name
264 compressed names are really weird. The "compression" doubles the
265 size. The idea is that it also means that compressed names conform
266 to the doman name system. See RFC1002.
267 ******************************************************************/
268 static int put_nmb_name(char *buf,int offset,struct nmb_name *name)
270 int ret,m;
271 fstring buf1;
272 char *p;
274 if (strcmp(name->name,"*") == 0) {
275 /* special case for wildcard name */
276 memset(buf1,'\0',20);
277 buf1[0] = '*';
278 buf1[15] = name->name_type;
279 } else {
280 slprintf(buf1, sizeof(buf1) - 1,"%-15.15s%c",name->name,name->name_type);
283 buf[offset] = 0x20;
285 ret = 34;
287 for (m=0;m<16;m++) {
288 buf[offset+1+2*m] = 'A' + ((buf1[m]>>4)&0xF);
289 buf[offset+2+2*m] = 'A' + (buf1[m]&0xF);
291 offset += 33;
293 buf[offset] = 0;
295 if (name->scope[0]) {
296 /* XXXX this scope handling needs testing */
297 ret += strlen(name->scope) + 1;
298 pstrcpy(&buf[offset+1],name->scope);
300 p = &buf[offset+1];
301 while ((p = strchr_m(p,'.'))) {
302 buf[offset] = PTR_DIFF(p,&buf[offset+1]);
303 offset += (buf[offset] + 1);
304 p = &buf[offset+1];
306 buf[offset] = strlen(&buf[offset+1]);
309 return(ret);
312 /*******************************************************************
313 useful for debugging messages
314 ******************************************************************/
315 char *nmb_namestr(struct nmb_name *n)
317 static int i=0;
318 static fstring ret[4];
319 char *p = ret[i];
321 if (!n->scope[0])
322 slprintf(p,sizeof(fstring)-1, "%s<%02x>",n->name,n->name_type);
323 else
324 slprintf(p,sizeof(fstring)-1, "%s<%02x>.%s",n->name,n->name_type,n->scope);
326 i = (i+1)%4;
327 return(p);
330 /*******************************************************************
331 allocate and parse some resource records
332 ******************************************************************/
333 static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length,
334 struct res_rec **recs, int count)
336 int i;
337 *recs = (struct res_rec *)malloc(sizeof(**recs)*count);
338 if (!*recs) return(False);
340 memset((char *)*recs,'\0',sizeof(**recs)*count);
342 for (i=0;i<count;i++) {
343 int l = parse_nmb_name(inbuf,*offset,length,&(*recs)[i].rr_name);
344 (*offset) += l;
345 if (!l || (*offset)+10 > length) {
346 SAFE_FREE(*recs);
347 return(False);
349 (*recs)[i].rr_type = RSVAL(inbuf,(*offset));
350 (*recs)[i].rr_class = RSVAL(inbuf,(*offset)+2);
351 (*recs)[i].ttl = RIVAL(inbuf,(*offset)+4);
352 (*recs)[i].rdlength = RSVAL(inbuf,(*offset)+8);
353 (*offset) += 10;
354 if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) ||
355 (*offset)+(*recs)[i].rdlength > length) {
356 SAFE_FREE(*recs);
357 return(False);
359 memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength);
360 (*offset) += (*recs)[i].rdlength;
362 return(True);
365 /*******************************************************************
366 put a resource record into a packet
367 ******************************************************************/
368 static int put_res_rec(char *buf,int offset,struct res_rec *recs,int count)
370 int ret=0;
371 int i;
373 for (i=0;i<count;i++) {
374 int l = put_nmb_name(buf,offset,&recs[i].rr_name);
375 offset += l;
376 ret += l;
377 RSSVAL(buf,offset,recs[i].rr_type);
378 RSSVAL(buf,offset+2,recs[i].rr_class);
379 RSIVAL(buf,offset+4,recs[i].ttl);
380 RSSVAL(buf,offset+8,recs[i].rdlength);
381 memcpy(buf+offset+10,recs[i].rdata,recs[i].rdlength);
382 offset += 10+recs[i].rdlength;
383 ret += 10+recs[i].rdlength;
386 return(ret);
389 /*******************************************************************
390 put a compressed name pointer record into a packet
391 ******************************************************************/
392 static int put_compressed_name_ptr(uchar *buf,int offset,struct res_rec *rec,int ptr_offset)
394 int ret=0;
395 buf[offset] = (0xC0 | ((ptr_offset >> 8) & 0xFF));
396 buf[offset+1] = (ptr_offset & 0xFF);
397 offset += 2;
398 ret += 2;
399 RSSVAL(buf,offset,rec->rr_type);
400 RSSVAL(buf,offset+2,rec->rr_class);
401 RSIVAL(buf,offset+4,rec->ttl);
402 RSSVAL(buf,offset+8,rec->rdlength);
403 memcpy(buf+offset+10,rec->rdata,rec->rdlength);
404 offset += 10+rec->rdlength;
405 ret += 10+rec->rdlength;
407 return(ret);
410 /*******************************************************************
411 parse a dgram packet. Return False if the packet can't be parsed
412 or is invalid for some reason, True otherwise
414 this is documented in section 4.4.1 of RFC1002
415 ******************************************************************/
416 static BOOL parse_dgram(char *inbuf,int length,struct dgram_packet *dgram)
418 int offset;
419 int flags;
421 memset((char *)dgram,'\0',sizeof(*dgram));
423 if (length < 14) return(False);
425 dgram->header.msg_type = CVAL(inbuf,0);
426 flags = CVAL(inbuf,1);
427 dgram->header.flags.node_type = (enum node_type)((flags>>2)&3);
428 if (flags & 1) dgram->header.flags.more = True;
429 if (flags & 2) dgram->header.flags.first = True;
430 dgram->header.dgm_id = RSVAL(inbuf,2);
431 putip((char *)&dgram->header.source_ip,inbuf+4);
432 dgram->header.source_port = RSVAL(inbuf,8);
433 dgram->header.dgm_length = RSVAL(inbuf,10);
434 dgram->header.packet_offset = RSVAL(inbuf,12);
436 offset = 14;
438 if (dgram->header.msg_type == 0x10 ||
439 dgram->header.msg_type == 0x11 ||
440 dgram->header.msg_type == 0x12) {
441 offset += parse_nmb_name(inbuf,offset,length,&dgram->source_name);
442 offset += parse_nmb_name(inbuf,offset,length,&dgram->dest_name);
445 if (offset >= length || (length-offset > sizeof(dgram->data)))
446 return(False);
448 dgram->datasize = length-offset;
449 memcpy(dgram->data,inbuf+offset,dgram->datasize);
451 return(True);
455 /*******************************************************************
456 parse a nmb packet. Return False if the packet can't be parsed
457 or is invalid for some reason, True otherwise
458 ******************************************************************/
459 static BOOL parse_nmb(char *inbuf,int length,struct nmb_packet *nmb)
461 int nm_flags,offset;
463 memset((char *)nmb,'\0',sizeof(*nmb));
465 if (length < 12) return(False);
467 /* parse the header */
468 nmb->header.name_trn_id = RSVAL(inbuf,0);
470 DEBUG(10,("parse_nmb: packet id = %d\n", nmb->header.name_trn_id));
472 nmb->header.opcode = (CVAL(inbuf,2) >> 3) & 0xF;
473 nmb->header.response = ((CVAL(inbuf,2)>>7)&1)?True:False;
474 nm_flags = ((CVAL(inbuf,2) & 0x7) << 4) + (CVAL(inbuf,3)>>4);
475 nmb->header.nm_flags.bcast = (nm_flags&1)?True:False;
476 nmb->header.nm_flags.recursion_available = (nm_flags&8)?True:False;
477 nmb->header.nm_flags.recursion_desired = (nm_flags&0x10)?True:False;
478 nmb->header.nm_flags.trunc = (nm_flags&0x20)?True:False;
479 nmb->header.nm_flags.authoritative = (nm_flags&0x40)?True:False;
480 nmb->header.rcode = CVAL(inbuf,3) & 0xF;
481 nmb->header.qdcount = RSVAL(inbuf,4);
482 nmb->header.ancount = RSVAL(inbuf,6);
483 nmb->header.nscount = RSVAL(inbuf,8);
484 nmb->header.arcount = RSVAL(inbuf,10);
486 if (nmb->header.qdcount) {
487 offset = parse_nmb_name(inbuf,12,length,&nmb->question.question_name);
488 if (!offset) return(False);
490 if (length - (12+offset) < 4) return(False);
491 nmb->question.question_type = RSVAL(inbuf,12+offset);
492 nmb->question.question_class = RSVAL(inbuf,12+offset+2);
494 offset += 12+4;
495 } else {
496 offset = 12;
499 /* and any resource records */
500 if (nmb->header.ancount &&
501 !parse_alloc_res_rec(inbuf,&offset,length,&nmb->answers,
502 nmb->header.ancount))
503 return(False);
505 if (nmb->header.nscount &&
506 !parse_alloc_res_rec(inbuf,&offset,length,&nmb->nsrecs,
507 nmb->header.nscount))
508 return(False);
510 if (nmb->header.arcount &&
511 !parse_alloc_res_rec(inbuf,&offset,length,&nmb->additional,
512 nmb->header.arcount))
513 return(False);
515 return(True);
518 /*******************************************************************
519 'Copy constructor' for an nmb packet
520 ******************************************************************/
521 static struct packet_struct *copy_nmb_packet(struct packet_struct *packet)
523 struct nmb_packet *nmb;
524 struct nmb_packet *copy_nmb;
525 struct packet_struct *pkt_copy;
527 if(( pkt_copy = (struct packet_struct *)malloc(sizeof(*packet))) == NULL)
529 DEBUG(0,("copy_nmb_packet: malloc fail.\n"));
530 return NULL;
533 /* Structure copy of entire thing. */
535 *pkt_copy = *packet;
537 /* Ensure this copy is not locked. */
538 pkt_copy->locked = False;
540 /* Ensure this copy has no resource records. */
541 nmb = &packet->packet.nmb;
542 copy_nmb = &pkt_copy->packet.nmb;
544 copy_nmb->answers = NULL;
545 copy_nmb->nsrecs = NULL;
546 copy_nmb->additional = NULL;
548 /* Now copy any resource records. */
550 if (nmb->answers)
552 if((copy_nmb->answers = (struct res_rec *)
553 malloc(nmb->header.ancount * sizeof(struct res_rec))) == NULL)
554 goto free_and_exit;
555 memcpy((char *)copy_nmb->answers, (char *)nmb->answers,
556 nmb->header.ancount * sizeof(struct res_rec));
558 if (nmb->nsrecs)
560 if((copy_nmb->nsrecs = (struct res_rec *)
561 malloc(nmb->header.nscount * sizeof(struct res_rec))) == NULL)
562 goto free_and_exit;
563 memcpy((char *)copy_nmb->nsrecs, (char *)nmb->nsrecs,
564 nmb->header.nscount * sizeof(struct res_rec));
566 if (nmb->additional)
568 if((copy_nmb->additional = (struct res_rec *)
569 malloc(nmb->header.arcount * sizeof(struct res_rec))) == NULL)
570 goto free_and_exit;
571 memcpy((char *)copy_nmb->additional, (char *)nmb->additional,
572 nmb->header.arcount * sizeof(struct res_rec));
575 return pkt_copy;
577 free_and_exit:
579 SAFE_FREE(copy_nmb->answers);
580 SAFE_FREE(copy_nmb->nsrecs);
581 SAFE_FREE(copy_nmb->additional);
582 SAFE_FREE(pkt_copy);
584 DEBUG(0,("copy_nmb_packet: malloc fail in resource records.\n"));
585 return NULL;
588 /*******************************************************************
589 'Copy constructor' for a dgram packet
590 ******************************************************************/
591 static struct packet_struct *copy_dgram_packet(struct packet_struct *packet)
593 struct packet_struct *pkt_copy;
595 if(( pkt_copy = (struct packet_struct *)malloc(sizeof(*packet))) == NULL)
597 DEBUG(0,("copy_dgram_packet: malloc fail.\n"));
598 return NULL;
601 /* Structure copy of entire thing. */
603 *pkt_copy = *packet;
605 /* Ensure this copy is not locked. */
606 pkt_copy->locked = False;
608 /* There are no additional pointers in a dgram packet,
609 we are finished. */
610 return pkt_copy;
613 /*******************************************************************
614 'Copy constructor' for a generic packet
615 ******************************************************************/
616 struct packet_struct *copy_packet(struct packet_struct *packet)
618 if(packet->packet_type == NMB_PACKET)
619 return copy_nmb_packet(packet);
620 else if (packet->packet_type == DGRAM_PACKET)
621 return copy_dgram_packet(packet);
622 return NULL;
625 /*******************************************************************
626 free up any resources associated with an nmb packet
627 ******************************************************************/
628 static void free_nmb_packet(struct nmb_packet *nmb)
630 SAFE_FREE(nmb->answers);
631 SAFE_FREE(nmb->nsrecs);
632 SAFE_FREE(nmb->additional);
635 /*******************************************************************
636 free up any resources associated with a dgram packet
637 ******************************************************************/
638 static void free_dgram_packet(struct dgram_packet *nmb)
640 /* We have nothing to do for a dgram packet. */
643 /*******************************************************************
644 free up any resources associated with a packet
645 ******************************************************************/
646 void free_packet(struct packet_struct *packet)
648 if (packet->locked)
649 return;
650 if (packet->packet_type == NMB_PACKET)
651 free_nmb_packet(&packet->packet.nmb);
652 else if (packet->packet_type == DGRAM_PACKET)
653 free_dgram_packet(&packet->packet.dgram);
654 ZERO_STRUCTPN(packet);
655 SAFE_FREE(packet);
658 /*******************************************************************
659 parse a packet buffer into a packet structure
660 ******************************************************************/
661 struct packet_struct *parse_packet(char *buf,int length,
662 enum packet_type packet_type)
664 extern struct in_addr lastip;
665 extern int lastport;
666 struct packet_struct *p;
667 BOOL ok=False;
669 p = (struct packet_struct *)malloc(sizeof(*p));
670 if (!p) return(NULL);
672 p->next = NULL;
673 p->prev = NULL;
674 p->ip = lastip;
675 p->port = lastport;
676 p->locked = False;
677 p->timestamp = time(NULL);
678 p->packet_type = packet_type;
680 switch (packet_type) {
681 case NMB_PACKET:
682 ok = parse_nmb(buf,length,&p->packet.nmb);
683 break;
685 case DGRAM_PACKET:
686 ok = parse_dgram(buf,length,&p->packet.dgram);
687 break;
690 if (!ok) {
691 free_packet(p);
692 return NULL;
695 return p;
698 /*******************************************************************
699 read a packet from a socket and parse it, returning a packet ready
700 to be used or put on the queue. This assumes a UDP socket
701 ******************************************************************/
702 struct packet_struct *read_packet(int fd,enum packet_type packet_type)
704 struct packet_struct *packet;
705 char buf[MAX_DGRAM_SIZE];
706 int length;
708 length = read_udp_socket(fd,buf,sizeof(buf));
709 if (length < MIN_DGRAM_SIZE) return(NULL);
711 packet = parse_packet(buf, length, packet_type);
712 if (!packet) return NULL;
714 packet->fd = fd;
716 num_good_receives++;
718 DEBUG(5,("Received a packet of len %d from (%s) port %d\n",
719 length, inet_ntoa(packet->ip), packet->port ) );
721 return(packet);
725 /*******************************************************************
726 send a udp packet on a already open socket
727 ******************************************************************/
728 static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port)
730 BOOL ret = False;
731 int i;
732 struct sockaddr_in sock_out;
734 /* set the address and port */
735 memset((char *)&sock_out,'\0',sizeof(sock_out));
736 putip((char *)&sock_out.sin_addr,(char *)&ip);
737 sock_out.sin_port = htons( port );
738 sock_out.sin_family = AF_INET;
740 DEBUG( 5, ( "Sending a packet of len %d to (%s) on port %d\n",
741 len, inet_ntoa(ip), port ) );
744 * Patch to fix asynch error notifications from Linux kernel.
747 for (i = 0; i < 5; i++) {
748 ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out, sizeof(sock_out)) >= 0);
749 if (ret || errno != ECONNREFUSED)
750 break;
753 if (!ret)
754 DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n",
755 inet_ntoa(ip),port,strerror(errno)));
757 if (ret)
758 num_good_sends++;
760 return(ret);
763 /*******************************************************************
764 build a dgram packet ready for sending
766 XXXX This currently doesn't handle packets too big for one
767 datagram. It should split them and use the packet_offset, more and
768 first flags to handle the fragmentation. Yuck.
770 [...but it isn't clear that we would ever need to send a
771 a fragmented NBT Datagram. The IP layer does its own
772 fragmentation to ensure that messages can fit into the path
773 MTU. It *is* important to be able to receive and rebuild
774 fragmented NBT datagrams, just in case someone out there
775 really has implemented this 'feature'. crh -)------ ]
777 ******************************************************************/
778 static int build_dgram(char *buf,struct packet_struct *p)
780 struct dgram_packet *dgram = &p->packet.dgram;
781 uchar *ubuf = (uchar *)buf;
782 int offset=0;
784 /* put in the header */
785 ubuf[0] = dgram->header.msg_type;
786 ubuf[1] = (((int)dgram->header.flags.node_type)<<2);
787 if (dgram->header.flags.more) ubuf[1] |= 1;
788 if (dgram->header.flags.first) ubuf[1] |= 2;
789 RSSVAL(ubuf,2,dgram->header.dgm_id);
790 putip(ubuf+4,(char *)&dgram->header.source_ip);
791 RSSVAL(ubuf,8,dgram->header.source_port);
792 RSSVAL(ubuf,12,dgram->header.packet_offset);
794 offset = 14;
796 if (dgram->header.msg_type == 0x10 ||
797 dgram->header.msg_type == 0x11 ||
798 dgram->header.msg_type == 0x12) {
799 offset += put_nmb_name((char *)ubuf,offset,&dgram->source_name);
800 offset += put_nmb_name((char *)ubuf,offset,&dgram->dest_name);
803 memcpy(ubuf+offset,dgram->data,dgram->datasize);
804 offset += dgram->datasize;
806 /* automatically set the dgm_length
807 * NOTE: RFC1002 says the dgm_length does *not*
808 * include the fourteen-byte header. crh
810 dgram->header.dgm_length = (offset - 14);
811 RSSVAL(ubuf,10,dgram->header.dgm_length);
813 return(offset);
816 /*******************************************************************
817 Build a nmb name
818 *******************************************************************/
820 void make_nmb_name( struct nmb_name *n, const char *name, int type)
822 memset( (char *)n, '\0', sizeof(struct nmb_name) );
823 push_ascii(n->name, name, 16, STR_TERMINATE|STR_UPPER);
824 n->name_type = (unsigned int)type & 0xFF;
825 StrnCpy( n->scope, global_scope(), 63 );
826 strupper( n->scope );
829 /*******************************************************************
830 Compare two nmb names
831 ******************************************************************/
833 BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2)
835 return ((n1->name_type == n2->name_type) &&
836 strequal(n1->name ,n2->name ) &&
837 strequal(n1->scope,n2->scope));
840 /*******************************************************************
841 build a nmb packet ready for sending
843 XXXX this currently relies on not being passed something that expands
844 to a packet too big for the buffer. Eventually this should be
845 changed to set the trunc bit so the receiver can request the rest
846 via tcp (when that becomes supported)
847 ******************************************************************/
848 static int build_nmb(char *buf,struct packet_struct *p)
850 struct nmb_packet *nmb = &p->packet.nmb;
851 uchar *ubuf = (uchar *)buf;
852 int offset=0;
854 /* put in the header */
855 RSSVAL(ubuf,offset,nmb->header.name_trn_id);
856 ubuf[offset+2] = (nmb->header.opcode & 0xF) << 3;
857 if (nmb->header.response) ubuf[offset+2] |= (1<<7);
858 if (nmb->header.nm_flags.authoritative &&
859 nmb->header.response) ubuf[offset+2] |= 0x4;
860 if (nmb->header.nm_flags.trunc) ubuf[offset+2] |= 0x2;
861 if (nmb->header.nm_flags.recursion_desired) ubuf[offset+2] |= 0x1;
862 if (nmb->header.nm_flags.recursion_available &&
863 nmb->header.response) ubuf[offset+3] |= 0x80;
864 if (nmb->header.nm_flags.bcast) ubuf[offset+3] |= 0x10;
865 ubuf[offset+3] |= (nmb->header.rcode & 0xF);
867 RSSVAL(ubuf,offset+4,nmb->header.qdcount);
868 RSSVAL(ubuf,offset+6,nmb->header.ancount);
869 RSSVAL(ubuf,offset+8,nmb->header.nscount);
870 RSSVAL(ubuf,offset+10,nmb->header.arcount);
872 offset += 12;
873 if (nmb->header.qdcount) {
874 /* XXXX this doesn't handle a qdcount of > 1 */
875 offset += put_nmb_name((char *)ubuf,offset,&nmb->question.question_name);
876 RSSVAL(ubuf,offset,nmb->question.question_type);
877 RSSVAL(ubuf,offset+2,nmb->question.question_class);
878 offset += 4;
881 if (nmb->header.ancount)
882 offset += put_res_rec((char *)ubuf,offset,nmb->answers,
883 nmb->header.ancount);
885 if (nmb->header.nscount)
886 offset += put_res_rec((char *)ubuf,offset,nmb->nsrecs,
887 nmb->header.nscount);
890 * The spec says we must put compressed name pointers
891 * in the following outgoing packets :
892 * NAME_REGISTRATION_REQUEST, NAME_REFRESH_REQUEST,
893 * NAME_RELEASE_REQUEST.
896 if((nmb->header.response == False) &&
897 ((nmb->header.opcode == NMB_NAME_REG_OPCODE) ||
898 (nmb->header.opcode == NMB_NAME_RELEASE_OPCODE) ||
899 (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_8) ||
900 (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_9) ||
901 (nmb->header.opcode == NMB_NAME_MULTIHOMED_REG_OPCODE)) &&
902 (nmb->header.arcount == 1)) {
904 offset += put_compressed_name_ptr(ubuf,offset,nmb->additional,12);
906 } else if (nmb->header.arcount) {
907 offset += put_res_rec((char *)ubuf,offset,nmb->additional,
908 nmb->header.arcount);
910 return(offset);
914 /*******************************************************************
915 linearise a packet
916 ******************************************************************/
917 int build_packet(char *buf, struct packet_struct *p)
919 int len = 0;
921 switch (p->packet_type) {
922 case NMB_PACKET:
923 len = build_nmb(buf,p);
924 break;
926 case DGRAM_PACKET:
927 len = build_dgram(buf,p);
928 break;
931 return len;
934 /*******************************************************************
935 send a packet_struct
936 ******************************************************************/
937 BOOL send_packet(struct packet_struct *p)
939 char buf[1024];
940 int len=0;
942 memset(buf,'\0',sizeof(buf));
944 len = build_packet(buf, p);
946 if (!len) return(False);
948 return(send_udp(p->fd,buf,len,p->ip,p->port));
951 /****************************************************************************
952 receive a packet with timeout on a open UDP filedescriptor
953 The timeout is in milliseconds
954 ***************************************************************************/
955 struct packet_struct *receive_packet(int fd,enum packet_type type,int t)
957 fd_set fds;
958 struct timeval timeout;
959 int ret;
961 FD_ZERO(&fds);
962 FD_SET(fd,&fds);
963 timeout.tv_sec = t/1000;
964 timeout.tv_usec = 1000*(t%1000);
966 if ((ret = sys_select_intr(fd+1,&fds,NULL,NULL,&timeout)) == -1) {
967 /* errno should be EBADF or EINVAL. */
968 DEBUG(0,("select returned -1, errno = %s (%d)\n", strerror(errno), errno));
969 return NULL;
972 if (ret == 0) /* timeout */
973 return NULL;
975 if (FD_ISSET(fd,&fds))
976 return(read_packet(fd,type));
978 return(NULL);
982 /****************************************************************************
983 receive a UDP/137 packet either via UDP or from the unexpected packet
984 queue. The packet must be a reply packet and have the specified trn_id
985 The timeout is in milliseconds
986 ***************************************************************************/
987 struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id)
989 struct packet_struct *p;
991 p = receive_packet(fd, NMB_PACKET, t);
993 if (p && p->packet.nmb.header.response &&
994 p->packet.nmb.header.name_trn_id == trn_id) {
995 return p;
997 if (p) free_packet(p);
999 /* try the unexpected packet queue */
1000 return receive_unexpected(NMB_PACKET, trn_id, NULL);
1003 /****************************************************************************
1004 receive a UDP/138 packet either via UDP or from the unexpected packet
1005 queue. The packet must be a reply packet and have the specified mailslot name
1006 The timeout is in milliseconds
1007 ***************************************************************************/
1008 struct packet_struct *receive_dgram_packet(int fd, int t, const char *mailslot_name)
1010 struct packet_struct *p;
1012 p = receive_packet(fd, DGRAM_PACKET, t);
1014 if (p && match_mailslot_name(p, mailslot_name)) {
1015 return p;
1017 if (p) free_packet(p);
1019 /* try the unexpected packet queue */
1020 return receive_unexpected(DGRAM_PACKET, 0, mailslot_name);
1024 /****************************************************************************
1025 see if a datagram has the right mailslot name
1026 ***************************************************************************/
1027 BOOL match_mailslot_name(struct packet_struct *p, const char *mailslot_name)
1029 struct dgram_packet *dgram = &p->packet.dgram;
1030 char *buf;
1032 buf = &dgram->data[0];
1033 buf -= 4;
1035 buf = smb_buf(buf);
1037 if (memcmp(buf, mailslot_name, strlen(mailslot_name)+1) == 0) {
1038 return True;
1041 return False;
1045 /****************************************************************************
1046 return the number of bits that match between two 4 character buffers
1047 ***************************************************************************/
1048 int matching_quad_bits(uchar *p1, uchar *p2)
1050 int i, j, ret = 0;
1051 for (i=0; i<4; i++) {
1052 if (p1[i] != p2[i]) break;
1053 ret += 8;
1056 if (i==4) return ret;
1058 for (j=0; j<8; j++) {
1059 if ((p1[i] & (1<<(7-j))) != (p2[i] & (1<<(7-j)))) break;
1060 ret++;
1063 return ret;
1067 static uchar sort_ip[4];
1069 /****************************************************************************
1070 compare two query reply records
1071 ***************************************************************************/
1072 static int name_query_comp(uchar *p1, uchar *p2)
1074 return matching_quad_bits(p2+2, sort_ip) - matching_quad_bits(p1+2, sort_ip);
1077 /****************************************************************************
1078 sort a set of 6 byte name query response records so that the IPs that
1079 have the most leading bits in common with the specified address come first
1080 ***************************************************************************/
1081 void sort_query_replies(char *data, int n, struct in_addr ip)
1083 if (n <= 1) return;
1085 putip(sort_ip, (char *)&ip);
1087 qsort(data, n, 6, QSORT_CAST name_query_comp);
1091 #define TRUNCATE_NETBIOS_NAME 1
1093 /*******************************************************************
1094 convert, possibly using a stupid microsoft-ism which has destroyed
1095 the transport independence of netbios (for CIFS vendors that usually
1096 use the Win95-type methods, not for NT to NT communication, which uses
1097 DCE/RPC and therefore full-length unicode strings...) a dns name into
1098 a netbios name.
1100 the netbios name (NOT necessarily null-terminated) is truncated to 15
1101 characters.
1103 ******************************************************************/
1104 char *dns_to_netbios_name(char *dns_name)
1106 static char netbios_name[16];
1107 int i;
1108 StrnCpy(netbios_name, dns_name, 15);
1109 netbios_name[15] = 0;
1111 #ifdef TRUNCATE_NETBIOS_NAME
1112 /* ok. this is because of a stupid microsoft-ism. if the called host
1113 name contains a '.', microsoft clients expect you to truncate the
1114 netbios name up to and including the '.' this even applies, by
1115 mistake, to workgroup (domain) names, which is _really_ daft.
1117 for (i = 15; i >= 0; i--)
1119 if (netbios_name[i] == '.')
1121 netbios_name[i] = 0;
1122 break;
1125 #endif /* TRUNCATE_NETBIOS_NAME */
1127 return netbios_name;
1131 /****************************************************************************
1132 interpret the weird netbios "name". Return the name type
1133 ****************************************************************************/
1134 static int name_interpret(char *in,char *out)
1136 int ret;
1137 int len = (*in++) / 2;
1139 *out=0;
1141 if (len > 30 || len<1) return(0);
1143 while (len--)
1145 if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
1146 *out = 0;
1147 return(0);
1149 *out = ((in[0]-'A')<<4) + (in[1]-'A');
1150 in += 2;
1151 out++;
1153 *out = 0;
1154 ret = out[-1];
1156 #ifdef NETBIOS_SCOPE
1157 /* Handle any scope names */
1158 while(*in)
1160 *out++ = '.'; /* Scope names are separated by periods */
1161 len = *(uchar *)in++;
1162 StrnCpy(out, in, len);
1163 out += len;
1164 *out=0;
1165 in += len;
1167 #endif
1168 return(ret);
1171 /****************************************************************************
1172 mangle a name into netbios format
1174 Note: <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
1175 ****************************************************************************/
1176 int name_mangle( char *In, char *Out, char name_type )
1178 int i;
1179 int c;
1180 int len;
1181 char buf[20];
1182 char *p = Out;
1184 /* Safely copy the input string, In, into buf[]. */
1185 (void)memset( buf, 0, 20 );
1186 if (strcmp(In,"*") == 0)
1187 buf[0] = '*';
1188 else
1189 (void)slprintf( buf, sizeof(buf) - 1, "%-15.15s%c", In, name_type );
1191 /* Place the length of the first field into the output buffer. */
1192 p[0] = 32;
1193 p++;
1195 /* Now convert the name to the rfc1001/1002 format. */
1196 for( i = 0; i < 16; i++ )
1198 c = toupper( buf[i] );
1199 p[i*2] = ( (c >> 4) & 0x000F ) + 'A';
1200 p[(i*2)+1] = (c & 0x000F) + 'A';
1202 p += 32;
1203 p[0] = '\0';
1205 /* Add the scope string. */
1206 for( i = 0, len = 0; *(global_scope()) != '\0'; i++, len++ )
1208 switch( (global_scope())[i] )
1210 case '\0':
1211 p[0] = len;
1212 if( len > 0 )
1213 p[len+1] = 0;
1214 return( name_len(Out) );
1215 case '.':
1216 p[0] = len;
1217 p += (len + 1);
1218 len = -1;
1219 break;
1220 default:
1221 p[len+1] = (global_scope())[i];
1222 break;
1226 return( name_len(Out) );
1227 } /* name_mangle */
1230 /****************************************************************************
1231 find a pointer to a netbios name
1232 ****************************************************************************/
1233 static char *name_ptr(char *buf,int ofs)
1235 uchar c = *(uchar *)(buf+ofs);
1237 if ((c & 0xC0) == 0xC0)
1239 uint16 l = RSVAL(buf, ofs) & 0x3FFF;
1240 DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
1241 return(buf + l);
1243 else
1244 return(buf+ofs);
1247 /****************************************************************************
1248 extract a netbios name from a buf
1249 ****************************************************************************/
1250 int name_extract(char *buf,int ofs,char *name)
1252 char *p = name_ptr(buf,ofs);
1253 int d = PTR_DIFF(p,buf+ofs);
1254 pstrcpy(name,"");
1255 if (d < -50 || d > 50) return(0);
1256 return(name_interpret(p,name));
1259 /****************************************************************************
1260 return the total storage length of a mangled name
1261 ****************************************************************************/
1262 int name_len(char *s1)
1264 /* NOTE: this argument _must_ be unsigned */
1265 uchar *s = (uchar *)s1;
1266 int len;
1268 /* If the two high bits of the byte are set, return 2. */
1269 if (0xC0 == (*s & 0xC0))
1270 return(2);
1272 /* Add up the length bytes. */
1273 for (len = 1; (*s); s += (*s) + 1) {
1274 len += *s + 1;
1275 SMB_ASSERT(len < 80);
1278 return(len);
1279 } /* name_len */