- got fed up of vuser_db spewing 150 lines of trash, made it possible
[Samba.git] / source / libsmb / nmblib.c
blob318331cbbd60b2e0e3e11c21330c91f781a69b1f
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 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;
32 int opcode;
33 } nmb_header_opcode_names[] = {
34 {"Query", 0 },
35 {"Registration", 5 },
36 {"Release", 6 },
37 {"WACK", 7 },
38 {"Refresh", 8 },
39 {"Refresh(altcode)", 9 },
40 {"Multi-homed Registration", 15 },
41 {0, -1 }
44 /****************************************************************************
45 * Lookup a nmb opcode name.
46 ****************************************************************************/
47 static char *lookup_opcode_name( int opcode )
49 struct opcode_names *op_namep;
50 int i;
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)
65 int i, j;
67 DEBUGADD( 4, ( " %s: nmb_name=%s rr_type=%d rr_class=%d ttl=%d\n",
68 hdr,
69 nmb_namestr(&res->rr_name),
70 res->rr_type,
71 res->rr_class,
72 res->ttl ) );
74 if( res->rdlength == 0 || res->rdata == NULL )
75 return;
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 uchar 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", (uchar)res->rdata[i+j]));
98 DEBUGADD(4, ("\n"));
102 /****************************************************************************
103 process a nmb packet
104 ****************************************************************************/
105 void debug_nmb_packet(struct packet_struct *p)
107 struct nmb_packet *nmb = &p->packet.nmb;
109 if( DEBUGLVL( 4 ) )
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),
115 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",
124 nmb->header.rcode,
125 nmb->header.qdcount,
126 nmb->header.ancount,
127 nmb->header.nscount,
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(uchar *ubuf,int *offset,int length,
157 BOOL *got_pointer,int *ret)
159 int loop_count=0;
161 while ((ubuf[*offset] & 0xC0) == 0xC0) {
162 if (!*got_pointer) (*ret) += 2;
163 (*got_pointer)=True;
164 (*offset) = ((ubuf[*offset] & ~0xC0)<<8) | ubuf[(*offset)+1];
165 if (loop_count++ == 10 || (*offset) < 0 || (*offset)>(length-2)) {
166 return(False);
169 return(True);
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)
178 int m,n=0;
179 uchar *ubuf = (uchar *)inbuf;
180 int ret = 0;
181 BOOL got_pointer=False;
182 int loop_count=0;
184 if (length - offset < 2)
185 return(0);
187 /* handle initial name pointers */
188 if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret))
189 return(0);
191 m = ubuf[offset];
193 if (!m)
194 return(0);
195 if ((m & 0xC0) || offset+m+2 > length)
196 return(0);
198 memset((char *)name,'\0',sizeof(*name));
200 /* the "compressed" part */
201 if (!got_pointer)
202 ret += m + 2;
203 offset++;
204 while (m > 0) {
205 uchar c1,c2;
206 c1 = ubuf[offset++]-'A';
207 c2 = ubuf[offset++]-'A';
208 if ((c1 & 0xF0) || (c2 & 0xF0) || (n > sizeof(name->name)-1))
209 return(0);
210 name->name[n++] = (c1<<4) | c2;
211 m -= 2;
213 name->name[n] = 0;
215 if (n==16) {
216 /* parse out the name type,
217 its always in the 16th byte of the name */
218 name->name_type = ((uchar)name->name[15]) & 0xff;
220 /* remove trailing spaces */
221 name->name[15] = 0;
222 n = 14;
223 while (n && name->name[n]==' ')
224 name->name[n--] = 0;
227 /* now the domain parts (if any) */
228 n = 0;
229 while (ubuf[offset]) {
230 /* we can have pointers within the domain part as well */
231 if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret))
232 return(0);
234 m = ubuf[offset];
236 * Don't allow null domain parts.
238 if (!m)
239 return(0);
240 if (!got_pointer)
241 ret += m+1;
242 if (n)
243 name->scope[n++] = '.';
244 if (m+2+offset>length || n+m+1>sizeof(name->scope))
245 return(0);
246 offset++;
247 while (m--)
248 name->scope[n++] = (char)ubuf[offset++];
251 * Watch for malicious loops.
253 if (loop_count++ == 10)
254 return 0;
256 name->scope[n++] = 0;
258 return(ret);
262 /*******************************************************************
263 put a compressed nmb name into a buffer. return the length of the
264 compressed name
266 compressed names are really weird. The "compression" doubles the
267 size. The idea is that it also means that compressed names conform
268 to the doman name system. See RFC1002.
269 ******************************************************************/
270 static int put_nmb_name(char *buf,int offset,struct nmb_name *name)
272 int ret,m;
273 fstring buf1;
274 char *p;
276 if (strcmp(name->name,"*") == 0) {
277 /* special case for wildcard name */
278 memset(buf1,'\0',20);
279 buf1[0] = '*';
280 buf1[15] = name->name_type;
281 } else {
282 slprintf(buf1, sizeof(buf1) - 1,"%-15.15s%c",name->name,name->name_type);
285 buf[offset] = 0x20;
287 ret = 34;
289 for (m=0;m<16;m++) {
290 buf[offset+1+2*m] = 'A' + ((buf1[m]>>4)&0xF);
291 buf[offset+2+2*m] = 'A' + (buf1[m]&0xF);
293 offset += 33;
295 buf[offset] = 0;
297 if (name->scope[0]) {
298 /* XXXX this scope handling needs testing */
299 ret += strlen(name->scope) + 1;
300 pstrcpy(&buf[offset+1],name->scope);
302 p = &buf[offset+1];
303 while ((p = strchr(p,'.'))) {
304 buf[offset] = PTR_DIFF(p,&buf[offset+1]);
305 offset += (buf[offset] + 1);
306 p = &buf[offset+1];
308 buf[offset] = strlen(&buf[offset+1]);
311 return(ret);
314 /*******************************************************************
315 useful for debugging messages
316 ******************************************************************/
317 char *nmb_namestr(struct nmb_name *n)
319 static int i=0;
320 static fstring ret[4];
321 char *p = ret[i];
323 if (!n->scope[0])
324 slprintf(p,sizeof(fstring)-1, "%s<%02x>",n->name,n->name_type);
325 else
326 slprintf(p,sizeof(fstring)-1, "%s<%02x>.%s",n->name,n->name_type,n->scope);
328 i = (i+1)%4;
329 return(p);
332 /*******************************************************************
333 useful for debugging messages
334 ******************************************************************/
335 void nmb_safe_namestr(struct nmb_name *n, char *str, size_t len)
337 if (!n->scope[0])
338 slprintf(str, len-1, "%s<%02x>",n->name,n->name_type);
339 else
340 slprintf(str, len-1, "%s<%02x>.%s",n->name,n->name_type,n->scope);
343 /*******************************************************************
344 allocate and parse some resource records
345 ******************************************************************/
346 static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length,
347 struct res_rec **recs, int count)
349 int i;
350 *recs = (struct res_rec *)malloc(sizeof(**recs)*count);
351 if (!*recs) return(False);
353 memset((char *)*recs,'\0',sizeof(**recs)*count);
355 for (i=0;i<count;i++) {
356 int l = parse_nmb_name(inbuf,*offset,length,&(*recs)[i].rr_name);
357 (*offset) += l;
358 if (!l || (*offset)+10 > length) {
359 free(*recs);
360 *recs = NULL;
361 return(False);
363 (*recs)[i].rr_type = RSVAL(inbuf,(*offset));
364 (*recs)[i].rr_class = RSVAL(inbuf,(*offset)+2);
365 (*recs)[i].ttl = RIVAL(inbuf,(*offset)+4);
366 (*recs)[i].rdlength = RSVAL(inbuf,(*offset)+8);
367 (*offset) += 10;
368 if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) ||
369 (*offset)+(*recs)[i].rdlength > length) {
370 free(*recs);
371 *recs = NULL;
372 return(False);
374 memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength);
375 (*offset) += (*recs)[i].rdlength;
377 return(True);
380 /*******************************************************************
381 put a resource record into a packet
382 ******************************************************************/
383 static int put_res_rec(char *buf,int offset,struct res_rec *recs,int count)
385 int ret=0;
386 int i;
388 for (i=0;i<count;i++) {
389 int l = put_nmb_name(buf,offset,&recs[i].rr_name);
390 offset += l;
391 ret += l;
392 RSSVAL(buf,offset,recs[i].rr_type);
393 RSSVAL(buf,offset+2,recs[i].rr_class);
394 RSIVAL(buf,offset+4,recs[i].ttl);
395 RSSVAL(buf,offset+8,recs[i].rdlength);
396 memcpy(buf+offset+10,recs[i].rdata,recs[i].rdlength);
397 offset += 10+recs[i].rdlength;
398 ret += 10+recs[i].rdlength;
401 return(ret);
404 /*******************************************************************
405 put a compressed name pointer record into a packet
406 ******************************************************************/
407 static int put_compressed_name_ptr(uchar *buf,int offset,struct res_rec *rec,int ptr_offset)
409 int ret=0;
410 buf[offset] = (0xC0 | ((ptr_offset >> 8) & 0xFF));
411 buf[offset+1] = (ptr_offset & 0xFF);
412 offset += 2;
413 ret += 2;
414 RSSVAL(buf,offset,rec->rr_type);
415 RSSVAL(buf,offset+2,rec->rr_class);
416 RSIVAL(buf,offset+4,rec->ttl);
417 RSSVAL(buf,offset+8,rec->rdlength);
418 memcpy(buf+offset+10,rec->rdata,rec->rdlength);
419 offset += 10+rec->rdlength;
420 ret += 10+rec->rdlength;
422 return(ret);
425 /*******************************************************************
426 parse a dgram packet. Return False if the packet can't be parsed
427 or is invalid for some reason, True otherwise
429 this is documented in section 4.4.1 of RFC1002
430 ******************************************************************/
431 static BOOL parse_dgram(char *inbuf,int length,struct dgram_packet *dgram)
433 int offset;
434 int flags;
436 memset((char *)dgram,'\0',sizeof(*dgram));
438 if (length < 14) return(False);
440 dgram->header.msg_type = CVAL(inbuf,0);
441 flags = CVAL(inbuf,1);
442 dgram->header.flags.node_type = (enum node_type)((flags>>2)&3);
443 if (flags & 1) dgram->header.flags.more = True;
444 if (flags & 2) dgram->header.flags.first = True;
445 dgram->header.dgm_id = RSVAL(inbuf,2);
446 putip((char *)&dgram->header.source_ip,inbuf+4);
447 dgram->header.source_port = RSVAL(inbuf,8);
448 dgram->header.dgm_length = RSVAL(inbuf,10);
449 dgram->header.packet_offset = RSVAL(inbuf,12);
451 offset = 14;
453 if (dgram->header.msg_type == 0x10 ||
454 dgram->header.msg_type == 0x11 ||
455 dgram->header.msg_type == 0x12) {
456 offset += parse_nmb_name(inbuf,offset,length,&dgram->source_name);
457 offset += parse_nmb_name(inbuf,offset,length,&dgram->dest_name);
460 if (offset >= length || (length-offset > sizeof(dgram->data)))
461 return(False);
463 dgram->datasize = length-offset;
464 memcpy(dgram->data,inbuf+offset,dgram->datasize);
466 return(True);
470 /*******************************************************************
471 parse a nmb packet. Return False if the packet can't be parsed
472 or is invalid for some reason, True otherwise
473 ******************************************************************/
474 static BOOL parse_nmb(char *inbuf,int length,struct nmb_packet *nmb)
476 int nm_flags,offset;
478 memset((char *)nmb,'\0',sizeof(*nmb));
480 if (length < 12) return(False);
482 /* parse the header */
483 nmb->header.name_trn_id = RSVAL(inbuf,0);
485 DEBUG(10,("parse_nmb: packet id = %d\n", nmb->header.name_trn_id));
487 nmb->header.opcode = (CVAL(inbuf,2) >> 3) & 0xF;
488 nmb->header.response = ((CVAL(inbuf,2)>>7)&1)?True:False;
489 nm_flags = ((CVAL(inbuf,2) & 0x7) << 4) + (CVAL(inbuf,3)>>4);
490 nmb->header.nm_flags.bcast = (nm_flags&1)?True:False;
491 nmb->header.nm_flags.recursion_available = (nm_flags&8)?True:False;
492 nmb->header.nm_flags.recursion_desired = (nm_flags&0x10)?True:False;
493 nmb->header.nm_flags.trunc = (nm_flags&0x20)?True:False;
494 nmb->header.nm_flags.authoritative = (nm_flags&0x40)?True:False;
495 nmb->header.rcode = CVAL(inbuf,3) & 0xF;
496 nmb->header.qdcount = RSVAL(inbuf,4);
497 nmb->header.ancount = RSVAL(inbuf,6);
498 nmb->header.nscount = RSVAL(inbuf,8);
499 nmb->header.arcount = RSVAL(inbuf,10);
501 if (nmb->header.qdcount) {
502 offset = parse_nmb_name(inbuf,12,length,&nmb->question.question_name);
503 if (!offset) return(False);
505 if (length - (12+offset) < 4) return(False);
506 nmb->question.question_type = RSVAL(inbuf,12+offset);
507 nmb->question.question_class = RSVAL(inbuf,12+offset+2);
509 offset += 12+4;
510 } else {
511 offset = 12;
514 /* and any resource records */
515 if (nmb->header.ancount &&
516 !parse_alloc_res_rec(inbuf,&offset,length,&nmb->answers,
517 nmb->header.ancount))
518 return(False);
520 if (nmb->header.nscount &&
521 !parse_alloc_res_rec(inbuf,&offset,length,&nmb->nsrecs,
522 nmb->header.nscount))
523 return(False);
525 if (nmb->header.arcount &&
526 !parse_alloc_res_rec(inbuf,&offset,length,&nmb->additional,
527 nmb->header.arcount))
528 return(False);
530 return(True);
533 /*******************************************************************
534 'Copy constructor' for an nmb packet
535 ******************************************************************/
536 static struct packet_struct *copy_nmb_packet(struct packet_struct *packet)
538 struct nmb_packet *nmb;
539 struct nmb_packet *copy_nmb;
540 struct packet_struct *pkt_copy;
542 if(( pkt_copy = (struct packet_struct *)malloc(sizeof(*packet))) == NULL)
544 DEBUG(0,("copy_nmb_packet: malloc fail.\n"));
545 return NULL;
548 /* Structure copy of entire thing. */
550 *pkt_copy = *packet;
552 /* Ensure this copy is not locked. */
553 pkt_copy->locked = False;
555 /* Ensure this copy has no resource records. */
556 nmb = &packet->packet.nmb;
557 copy_nmb = &pkt_copy->packet.nmb;
559 copy_nmb->answers = NULL;
560 copy_nmb->nsrecs = NULL;
561 copy_nmb->additional = NULL;
563 /* Now copy any resource records. */
565 if (nmb->answers)
567 if((copy_nmb->answers = (struct res_rec *)
568 malloc(nmb->header.ancount * sizeof(struct res_rec))) == NULL)
569 goto free_and_exit;
570 memcpy((char *)copy_nmb->answers, (char *)nmb->answers,
571 nmb->header.ancount * sizeof(struct res_rec));
573 if (nmb->nsrecs)
575 if((copy_nmb->nsrecs = (struct res_rec *)
576 malloc(nmb->header.nscount * sizeof(struct res_rec))) == NULL)
577 goto free_and_exit;
578 memcpy((char *)copy_nmb->nsrecs, (char *)nmb->nsrecs,
579 nmb->header.nscount * sizeof(struct res_rec));
581 if (nmb->additional)
583 if((copy_nmb->additional = (struct res_rec *)
584 malloc(nmb->header.arcount * sizeof(struct res_rec))) == NULL)
585 goto free_and_exit;
586 memcpy((char *)copy_nmb->additional, (char *)nmb->additional,
587 nmb->header.arcount * sizeof(struct res_rec));
590 return pkt_copy;
592 free_and_exit:
594 if(copy_nmb->answers) {
595 free((char *)copy_nmb->answers);
596 copy_nmb->answers = NULL;
598 if(copy_nmb->nsrecs) {
599 free((char *)copy_nmb->nsrecs);
600 copy_nmb->nsrecs = NULL;
602 if(copy_nmb->additional) {
603 free((char *)copy_nmb->additional);
604 copy_nmb->additional = NULL;
606 free((char *)pkt_copy);
608 DEBUG(0,("copy_nmb_packet: malloc fail in resource records.\n"));
609 return NULL;
612 /*******************************************************************
613 'Copy constructor' for a dgram packet
614 ******************************************************************/
615 static struct packet_struct *copy_dgram_packet(struct packet_struct *packet)
617 struct packet_struct *pkt_copy;
619 if(( pkt_copy = (struct packet_struct *)malloc(sizeof(*packet))) == NULL)
621 DEBUG(0,("copy_dgram_packet: malloc fail.\n"));
622 return NULL;
625 /* Structure copy of entire thing. */
627 *pkt_copy = *packet;
629 /* Ensure this copy is not locked. */
630 pkt_copy->locked = False;
632 /* There are no additional pointers in a dgram packet,
633 we are finished. */
634 return pkt_copy;
637 /*******************************************************************
638 'Copy constructor' for a generic packet
639 ******************************************************************/
640 struct packet_struct *copy_packet(struct packet_struct *packet)
642 if(packet->packet_type == NMB_PACKET)
643 return copy_nmb_packet(packet);
644 else if (packet->packet_type == DGRAM_PACKET)
645 return copy_dgram_packet(packet);
646 return NULL;
649 /*******************************************************************
650 free up any resources associated with an nmb packet
651 ******************************************************************/
652 static void free_nmb_packet(struct nmb_packet *nmb)
654 if (nmb->answers) {
655 free(nmb->answers);
656 nmb->answers = NULL;
658 if (nmb->nsrecs) {
659 free(nmb->nsrecs);
660 nmb->nsrecs = NULL;
662 if (nmb->additional) {
663 free(nmb->additional);
664 nmb->additional = NULL;
668 /*******************************************************************
669 free up any resources associated with a dgram packet
670 ******************************************************************/
671 static void free_dgram_packet(struct dgram_packet *nmb)
673 /* We have nothing to do for a dgram packet. */
676 /*******************************************************************
677 free up any resources associated with a packet
678 ******************************************************************/
679 void free_packet(struct packet_struct *packet)
681 if (packet->locked)
682 return;
683 if (packet->packet_type == NMB_PACKET)
684 free_nmb_packet(&packet->packet.nmb);
685 else if (packet->packet_type == DGRAM_PACKET)
686 free_dgram_packet(&packet->packet.dgram);
687 ZERO_STRUCTPN(packet);
688 free(packet);
691 /*******************************************************************
692 parse a packet buffer into a packet structure
693 ******************************************************************/
694 struct packet_struct *parse_packet(char *buf,int length,
695 enum packet_type packet_type)
697 extern struct in_addr lastip;
698 extern int lastport;
699 struct packet_struct *p;
700 BOOL ok=False;
702 p = (struct packet_struct *)malloc(sizeof(*p));
703 if (!p) return(NULL);
705 p->next = NULL;
706 p->prev = NULL;
707 p->ip = lastip;
708 p->port = lastport;
709 p->locked = False;
710 p->timestamp = time(NULL);
711 p->packet_type = packet_type;
713 switch (packet_type) {
714 case NMB_PACKET:
715 ok = parse_nmb(buf,length,&p->packet.nmb);
716 break;
718 case DGRAM_PACKET:
719 ok = parse_dgram(buf,length,&p->packet.dgram);
720 break;
723 if (!ok) {
724 free_packet(p);
725 return NULL;
728 return p;
731 /*******************************************************************
732 read a packet from a socket and parse it, returning a packet ready
733 to be used or put on the queue. This assumes a UDP socket
734 ******************************************************************/
735 struct packet_struct *read_packet(int fd,enum packet_type packet_type)
737 struct packet_struct *packet;
738 char buf[MAX_DGRAM_SIZE];
739 int length;
741 length = read_udp_socket(fd,buf,sizeof(buf));
742 if (length < MIN_DGRAM_SIZE) return(NULL);
744 packet = parse_packet(buf, length, packet_type);
745 if (!packet) return NULL;
747 packet->fd = fd;
749 num_good_receives++;
751 DEBUG(5,("Received a packet of len %d from (%s) port %d\n",
752 length, inet_ntoa(packet->ip), packet->port ) );
754 return(packet);
758 /*******************************************************************
759 send a udp packet on a already open socket
760 ******************************************************************/
761 static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port)
763 BOOL ret;
764 struct sockaddr_in sock_out;
766 /* set the address and port */
767 memset((char *)&sock_out,'\0',sizeof(sock_out));
768 putip((char *)&sock_out.sin_addr,(char *)&ip);
769 sock_out.sin_port = htons( port );
770 sock_out.sin_family = AF_INET;
772 DEBUG( 5, ( "Sending a packet of len %d to (%s) on port %d\n",
773 len, inet_ntoa(ip), port ) );
775 ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out,
776 sizeof(sock_out)) >= 0);
778 if (!ret)
779 DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n",
780 inet_ntoa(ip),port,strerror(errno)));
782 if (ret)
783 num_good_sends++;
785 return(ret);
788 /*******************************************************************
789 build a dgram packet ready for sending
791 XXXX This currently doesn't handle packets too big for one
792 datagram. It should split them and use the packet_offset, more and
793 first flags to handle the fragmentation. Yuck.
794 ******************************************************************/
795 static int build_dgram(char *buf,struct packet_struct *p)
797 struct dgram_packet *dgram = &p->packet.dgram;
798 uchar *ubuf = (uchar *)buf;
799 int offset=0;
801 /* put in the header */
802 ubuf[0] = dgram->header.msg_type;
803 ubuf[1] = (((int)dgram->header.flags.node_type)<<2) + 0x10;
804 if (dgram->header.flags.more) ubuf[1] |= 1;
805 if (dgram->header.flags.first) ubuf[1] |= 2;
806 RSSVAL(ubuf,2,dgram->header.dgm_id);
807 putip(ubuf+4,(char *)&dgram->header.source_ip);
808 RSSVAL(ubuf,8,dgram->header.source_port);
809 RSSVAL(ubuf,12,dgram->header.packet_offset);
811 offset = 14;
813 if (dgram->header.msg_type == 0x10 ||
814 dgram->header.msg_type == 0x11 ||
815 dgram->header.msg_type == 0x12) {
816 offset += put_nmb_name((char *)ubuf,offset,&dgram->source_name);
817 offset += put_nmb_name((char *)ubuf,offset,&dgram->dest_name);
820 memcpy(ubuf+offset,dgram->data,dgram->datasize);
821 offset += dgram->datasize;
823 /* automatically set the dgm_length */
824 dgram->header.dgm_length = offset;
825 RSSVAL(ubuf,10,dgram->header.dgm_length);
827 return(offset);
830 /*******************************************************************
831 build a nmb name
832 *******************************************************************/
833 void make_nmb_name( struct nmb_name *n, const char *name, int type)
835 extern pstring global_scope;
836 memset( (char *)n, '\0', sizeof(struct nmb_name) );
837 StrnCpy( n->name, name, 15 );
838 strupper( n->name );
839 n->name_type = (unsigned int)type & 0xFF;
840 StrnCpy( n->scope, global_scope, 63 );
841 strupper( n->scope );
844 /*******************************************************************
845 Compare two nmb names
846 ******************************************************************/
848 BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2)
850 return ((n1->name_type == n2->name_type) &&
851 strequal(n1->name ,n2->name ) &&
852 strequal(n1->scope,n2->scope));
855 /*******************************************************************
856 build a nmb packet ready for sending
858 XXXX this currently relies on not being passed something that expands
859 to a packet too big for the buffer. Eventually this should be
860 changed to set the trunc bit so the receiver can request the rest
861 via tcp (when that becomes supported)
862 ******************************************************************/
863 static int build_nmb(char *buf,struct packet_struct *p)
865 struct nmb_packet *nmb = &p->packet.nmb;
866 uchar *ubuf = (uchar *)buf;
867 int offset=0;
869 /* put in the header */
870 RSSVAL(ubuf,offset,nmb->header.name_trn_id);
871 ubuf[offset+2] = (nmb->header.opcode & 0xF) << 3;
872 if (nmb->header.response) ubuf[offset+2] |= (1<<7);
873 if (nmb->header.nm_flags.authoritative &&
874 nmb->header.response) ubuf[offset+2] |= 0x4;
875 if (nmb->header.nm_flags.trunc) ubuf[offset+2] |= 0x2;
876 if (nmb->header.nm_flags.recursion_desired) ubuf[offset+2] |= 0x1;
877 if (nmb->header.nm_flags.recursion_available &&
878 nmb->header.response) ubuf[offset+3] |= 0x80;
879 if (nmb->header.nm_flags.bcast) ubuf[offset+3] |= 0x10;
880 ubuf[offset+3] |= (nmb->header.rcode & 0xF);
882 RSSVAL(ubuf,offset+4,nmb->header.qdcount);
883 RSSVAL(ubuf,offset+6,nmb->header.ancount);
884 RSSVAL(ubuf,offset+8,nmb->header.nscount);
885 RSSVAL(ubuf,offset+10,nmb->header.arcount);
887 offset += 12;
888 if (nmb->header.qdcount) {
889 /* XXXX this doesn't handle a qdcount of > 1 */
890 offset += put_nmb_name((char *)ubuf,offset,&nmb->question.question_name);
891 RSSVAL(ubuf,offset,nmb->question.question_type);
892 RSSVAL(ubuf,offset+2,nmb->question.question_class);
893 offset += 4;
896 if (nmb->header.ancount)
897 offset += put_res_rec((char *)ubuf,offset,nmb->answers,
898 nmb->header.ancount);
900 if (nmb->header.nscount)
901 offset += put_res_rec((char *)ubuf,offset,nmb->nsrecs,
902 nmb->header.nscount);
905 * The spec says we must put compressed name pointers
906 * in the following outgoing packets :
907 * NAME_REGISTRATION_REQUEST, NAME_REFRESH_REQUEST,
908 * NAME_RELEASE_REQUEST.
911 if((nmb->header.response == False) &&
912 ((nmb->header.opcode == NMB_NAME_REG_OPCODE) ||
913 (nmb->header.opcode == NMB_NAME_RELEASE_OPCODE) ||
914 (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_8) ||
915 (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_9) ||
916 (nmb->header.opcode == NMB_NAME_MULTIHOMED_REG_OPCODE)) &&
917 (nmb->header.arcount == 1)) {
919 offset += put_compressed_name_ptr(ubuf,offset,nmb->additional,12);
921 } else if (nmb->header.arcount) {
922 offset += put_res_rec((char *)ubuf,offset,nmb->additional,
923 nmb->header.arcount);
925 return(offset);
929 /*******************************************************************
930 linearise a packet
931 ******************************************************************/
932 int build_packet(char *buf, struct packet_struct *p)
934 int len = 0;
936 switch (p->packet_type) {
937 case NMB_PACKET:
938 len = build_nmb(buf,p);
939 break;
941 case DGRAM_PACKET:
942 len = build_dgram(buf,p);
943 break;
946 return len;
949 /*******************************************************************
950 send a packet_struct
951 ******************************************************************/
952 BOOL send_packet(struct packet_struct *p)
954 char buf[1024];
955 int len=0;
957 memset(buf,'\0',sizeof(buf));
959 len = build_packet(buf, p);
961 if (!len) return(False);
963 return(send_udp(p->fd,buf,len,p->ip,p->port));
966 /****************************************************************************
967 receive a packet with timeout on a open UDP filedescriptor
968 The timeout is in milliseconds
969 ***************************************************************************/
970 struct packet_struct *receive_packet(int fd,enum packet_type type,int t)
972 fd_set fds;
973 struct timeval timeout;
975 FD_ZERO(&fds);
976 FD_SET(fd,&fds);
977 timeout.tv_sec = t/1000;
978 timeout.tv_usec = 1000*(t%1000);
980 sys_select(fd+1,&fds,NULL,&timeout);
982 if (FD_ISSET(fd,&fds))
983 return(read_packet(fd,type));
985 return(NULL);
989 /****************************************************************************
990 receive a UDP/137 packet either via UDP or from the unexpected packet
991 queue. The packet must be a reply packet and have the specified trn_id
992 The timeout is in milliseconds
993 ***************************************************************************/
994 struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id)
996 struct packet_struct *p;
998 p = receive_packet(fd, NMB_PACKET, t);
1000 if (p && p->packet.nmb.header.response &&
1001 p->packet.nmb.header.name_trn_id == trn_id) {
1002 return p;
1004 if (p) free_packet(p);
1006 /* try the unexpected packet queue */
1007 return receive_unexpected(NMB_PACKET, trn_id, NULL);
1010 /****************************************************************************
1011 receive a UDP/138 packet either via UDP or from the unexpected packet
1012 queue. The packet must be a reply packet and have the specified mailslot name
1013 The timeout is in milliseconds
1014 ***************************************************************************/
1015 struct packet_struct *receive_dgram_packet(int fd, int t, char *mailslot_name)
1017 struct packet_struct *p;
1019 p = receive_packet(fd, DGRAM_PACKET, t);
1021 if (p && match_mailslot_name(p, mailslot_name)) {
1022 return p;
1024 if (p) free_packet(p);
1026 /* try the unexpected packet queue */
1027 return receive_unexpected(DGRAM_PACKET, 0, mailslot_name);
1031 /****************************************************************************
1032 see if a datagram has the right mailslot name
1033 ***************************************************************************/
1034 BOOL match_mailslot_name(struct packet_struct *p, char *mailslot_name)
1036 struct dgram_packet *dgram = &p->packet.dgram;
1037 char *buf;
1039 buf = &dgram->data[0];
1040 buf -= 4;
1042 buf = smb_buf(buf);
1044 if (memcmp(buf, mailslot_name, strlen(mailslot_name)+1) == 0) {
1045 return True;
1048 return False;
1052 /****************************************************************************
1053 return the number of bits that match between two 4 character buffers
1054 ***************************************************************************/
1055 static int matching_bits(uchar *p1, uchar *p2)
1057 int i, j, ret = 0;
1058 for (i=0; i<4; i++) {
1059 if (p1[i] != p2[i]) break;
1060 ret += 8;
1063 if (i==4) return ret;
1065 for (j=0; j<8; j++) {
1066 if ((p1[i] & (1<<(7-j))) != (p2[i] & (1<<(7-j)))) break;
1067 ret++;
1070 return ret;
1074 static uchar sort_ip[4];
1076 /****************************************************************************
1077 compare two query reply records
1078 ***************************************************************************/
1079 static int name_query_comp(uchar *p1, uchar *p2)
1081 return matching_bits(p2+2, sort_ip) - matching_bits(p1+2, sort_ip);
1084 /****************************************************************************
1085 sort a set of 6 byte name query response records so that the IPs that
1086 have the most leading bits in common with the specified address come first
1087 ***************************************************************************/
1088 void sort_query_replies(char *data, int n, struct in_addr ip)
1090 if (n <= 1) return;
1092 putip(sort_ip, (char *)&ip);
1094 qsort(data, n, 6, QSORT_CAST name_query_comp);
1098 #define TRUNCATE_NETBIOS_NAME 1
1100 /*******************************************************************
1101 convert, possibly using a stupid microsoft-ism which has destroyed
1102 the transport independence of netbios (for CIFS vendors that usually
1103 use the Win95-type methods, not for NT to NT communication, which uses
1104 DCE/RPC and therefore full-length unicode strings...) a dns name into
1105 a netbios name.
1107 the netbios name (NOT necessarily null-terminated) is truncated to 15
1108 characters.
1110 ******************************************************************/
1111 char *dns_to_netbios_name(char *dns_name)
1113 static char netbios_name[16];
1114 int i;
1115 StrnCpy(netbios_name, dns_name, 15);
1116 netbios_name[15] = 0;
1118 #ifdef TRUNCATE_NETBIOS_NAME
1119 /* ok. this is because of a stupid microsoft-ism. if the called host
1120 name contains a '.', microsoft clients expect you to truncate the
1121 netbios name up to and including the '.' this even applies, by
1122 mistake, to workgroup (domain) names, which is _really_ daft.
1124 for (i = 15; i >= 0; i--)
1126 if (netbios_name[i] == '.')
1128 netbios_name[i] = 0;
1129 break;
1132 #endif /* TRUNCATE_NETBIOS_NAME */
1134 return netbios_name;
1138 /****************************************************************************
1139 interpret the weird netbios "name". Return the name type
1140 ****************************************************************************/
1141 static int name_interpret(char *in,char *out)
1143 int ret;
1144 int len = (*in++) / 2;
1146 *out=0;
1148 if (len > 30 || len<1) return(0);
1150 while (len--)
1152 if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
1153 *out = 0;
1154 return(0);
1156 *out = ((in[0]-'A')<<4) + (in[1]-'A');
1157 in += 2;
1158 out++;
1160 *out = 0;
1161 ret = out[-1];
1163 #ifdef NETBIOS_SCOPE
1164 /* Handle any scope names */
1165 while(*in)
1167 *out++ = '.'; /* Scope names are separated by periods */
1168 len = *(uchar *)in++;
1169 StrnCpy(out, in, len);
1170 out += len;
1171 *out=0;
1172 in += len;
1174 #endif
1175 return(ret);
1178 /****************************************************************************
1179 mangle a name into netbios format
1181 Note: <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
1182 ****************************************************************************/
1183 int name_mangle( char *In, char *Out, char name_type )
1185 int i;
1186 int c;
1187 int len;
1188 char buf[20];
1189 char *p = Out;
1190 extern pstring global_scope;
1192 /* Safely copy the input string, In, into buf[]. */
1193 (void)memset( buf, 0, 20 );
1194 if (strcmp(In,"*") == 0)
1195 buf[0] = '*';
1196 else
1197 (void)slprintf( buf, sizeof(buf) - 1, "%-15.15s%c", In, name_type );
1199 /* Place the length of the first field into the output buffer. */
1200 p[0] = 32;
1201 p++;
1203 /* Now convert the name to the rfc1001/1002 format. */
1204 for( i = 0; i < 16; i++ )
1206 c = toupper( buf[i] );
1207 p[i*2] = ( (c >> 4) & 0x000F ) + 'A';
1208 p[(i*2)+1] = (c & 0x000F) + 'A';
1210 p += 32;
1211 p[0] = '\0';
1213 /* Add the scope string. */
1214 for( i = 0, len = 0; NULL != global_scope; i++, len++ )
1216 switch( global_scope[i] )
1218 case '\0':
1219 p[0] = len;
1220 if( len > 0 )
1221 p[len+1] = 0;
1222 return( name_len(Out) );
1223 case '.':
1224 p[0] = len;
1225 p += (len + 1);
1226 len = -1;
1227 break;
1228 default:
1229 p[len+1] = global_scope[i];
1230 break;
1234 return( name_len(Out) );
1235 } /* name_mangle */
1238 /****************************************************************************
1239 find a pointer to a netbios name
1240 ****************************************************************************/
1241 static char *name_ptr(char *buf,int ofs)
1243 uchar c = *(uchar *)(buf+ofs);
1245 if ((c & 0xC0) == 0xC0)
1247 uint16 l = RSVAL(buf, ofs) & 0x3FFF;
1248 DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
1249 return(buf + l);
1251 else
1252 return(buf+ofs);
1255 /****************************************************************************
1256 extract a netbios name from a buf
1257 ****************************************************************************/
1258 int name_extract(char *buf,int ofs,char *name)
1260 char *p = name_ptr(buf,ofs);
1261 int d = PTR_DIFF(p,buf+ofs);
1262 pstrcpy(name,"");
1263 if (d < -50 || d > 50) return(0);
1264 return(name_interpret(p,name));
1267 /****************************************************************************
1268 return the total storage length of a mangled name
1269 ****************************************************************************/
1270 int name_len(char *s1)
1272 /* NOTE: this argument _must_ be unsigned */
1273 uchar *s = (uchar *)s1;
1274 int len;
1276 /* If the two high bits of the byte are set, return 2. */
1277 if (0xC0 == (*s & 0xC0))
1278 return(2);
1280 /* Add up the length bytes. */
1281 for (len = 1; (*s); s += (*s) + 1) {
1282 len += *s + 1;
1283 SMB_ASSERT(len < 80);
1286 return(len);
1287 } /* name_len */