r11830: patch from Rashid N. Achilov <shelton@granch.ru> to add descriptions for...
[Samba.git] / source / libsmb / nmblib.c
blob164f85be7bf13146242d9f1c1abeff504edbf61b
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 extern struct in_addr lastip;
25 extern int lastport;
27 int num_good_sends = 0;
28 int num_good_receives = 0;
30 static const struct opcode_names {
31 const 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 ****************************************************************************/
48 static const char *lookup_opcode_name( int opcode )
50 const struct opcode_names *op_namep;
51 int i;
53 for(i = 0; nmb_header_opcode_names[i].nmb_opcode_name != 0; i++) {
54 op_namep = &nmb_header_opcode_names[i];
55 if(opcode == op_namep->opcode)
56 return op_namep->nmb_opcode_name;
58 return "<unknown opcode>";
61 /****************************************************************************
62 Print out a res_rec structure.
63 ****************************************************************************/
65 static void debug_nmb_res_rec(struct res_rec *res, const char *hdr)
67 int i, j;
69 DEBUGADD( 4, ( " %s: nmb_name=%s rr_type=%d rr_class=%d ttl=%d\n",
70 hdr,
71 nmb_namestr(&res->rr_name),
72 res->rr_type,
73 res->rr_class,
74 res->ttl ) );
76 if( res->rdlength == 0 || res->rdata == NULL )
77 return;
79 for (i = 0; i < res->rdlength; i+= MAX_NETBIOSNAME_LEN) {
80 DEBUGADD(4, (" %s %3x char ", hdr, i));
82 for (j = 0; j < MAX_NETBIOSNAME_LEN; j++) {
83 unsigned char x = res->rdata[i+j];
84 if (x < 32 || x > 127)
85 x = '.';
87 if (i+j >= res->rdlength)
88 break;
89 DEBUGADD(4, ("%c", x));
92 DEBUGADD(4, (" hex "));
94 for (j = 0; j < MAX_NETBIOSNAME_LEN; j++) {
95 if (i+j >= res->rdlength)
96 break;
97 DEBUGADD(4, ("%02X", (unsigned char)res->rdata[i+j]));
100 DEBUGADD(4, ("\n"));
104 /****************************************************************************
105 Process a nmb packet.
106 ****************************************************************************/
108 void debug_nmb_packet(struct packet_struct *p)
110 struct nmb_packet *nmb = &p->packet.nmb;
112 if( DEBUGLVL( 4 ) ) {
113 dbgtext( "nmb packet from %s(%d) header: id=%d opcode=%s(%d) response=%s\n",
114 inet_ntoa(p->ip), p->port,
115 nmb->header.name_trn_id,
116 lookup_opcode_name(nmb->header.opcode),
117 nmb->header.opcode,
118 BOOLSTR(nmb->header.response) );
119 dbgtext( " header: flags: bcast=%s rec_avail=%s rec_des=%s trunc=%s auth=%s\n",
120 BOOLSTR(nmb->header.nm_flags.bcast),
121 BOOLSTR(nmb->header.nm_flags.recursion_available),
122 BOOLSTR(nmb->header.nm_flags.recursion_desired),
123 BOOLSTR(nmb->header.nm_flags.trunc),
124 BOOLSTR(nmb->header.nm_flags.authoritative) );
125 dbgtext( " header: rcode=%d qdcount=%d ancount=%d nscount=%d arcount=%d\n",
126 nmb->header.rcode,
127 nmb->header.qdcount,
128 nmb->header.ancount,
129 nmb->header.nscount,
130 nmb->header.arcount );
133 if (nmb->header.qdcount) {
134 DEBUGADD( 4, ( " question: q_name=%s q_type=%d q_class=%d\n",
135 nmb_namestr(&nmb->question.question_name),
136 nmb->question.question_type,
137 nmb->question.question_class) );
140 if (nmb->answers && nmb->header.ancount) {
141 debug_nmb_res_rec(nmb->answers,"answers");
143 if (nmb->nsrecs && nmb->header.nscount) {
144 debug_nmb_res_rec(nmb->nsrecs,"nsrecs");
146 if (nmb->additional && nmb->header.arcount) {
147 debug_nmb_res_rec(nmb->additional,"additional");
151 /*******************************************************************
152 Handle "compressed" name pointers.
153 ******************************************************************/
155 static BOOL handle_name_ptrs(unsigned char *ubuf,int *offset,int length,
156 BOOL *got_pointer,int *ret)
158 int loop_count=0;
160 while ((ubuf[*offset] & 0xC0) == 0xC0) {
161 if (!*got_pointer)
162 (*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 ******************************************************************/
177 static int parse_nmb_name(char *inbuf,int ofs,int length, struct nmb_name *name)
179 int m,n=0;
180 unsigned char *ubuf = (unsigned char *)inbuf;
181 int ret = 0;
182 BOOL got_pointer=False;
183 int loop_count=0;
184 int offset = ofs;
186 if (length - offset < 2)
187 return(0);
189 /* handle initial name pointers */
190 if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret))
191 return(0);
193 m = ubuf[offset];
195 if (!m)
196 return(0);
197 if ((m & 0xC0) || offset+m+2 > length)
198 return(0);
200 memset((char *)name,'\0',sizeof(*name));
202 /* the "compressed" part */
203 if (!got_pointer)
204 ret += m + 2;
205 offset++;
206 while (m > 0) {
207 unsigned char c1,c2;
208 c1 = ubuf[offset++]-'A';
209 c2 = ubuf[offset++]-'A';
210 if ((c1 & 0xF0) || (c2 & 0xF0) || (n > sizeof(name->name)-1))
211 return(0);
212 name->name[n++] = (c1<<4) | c2;
213 m -= 2;
215 name->name[n] = 0;
217 if (n==MAX_NETBIOSNAME_LEN) {
218 /* parse out the name type, its always in the 16th byte of the name */
219 name->name_type = ((unsigned char)name->name[15]) & 0xff;
221 /* remove trailing spaces */
222 name->name[15] = 0;
223 n = 14;
224 while (n && name->name[n]==' ')
225 name->name[n--] = 0;
228 /* now the domain parts (if any) */
229 n = 0;
230 while (ubuf[offset]) {
231 /* we can have pointers within the domain part as well */
232 if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret))
233 return(0);
235 m = ubuf[offset];
237 * Don't allow null domain parts.
239 if (!m)
240 return(0);
241 if (!got_pointer)
242 ret += m+1;
243 if (n)
244 name->scope[n++] = '.';
245 if (m+2+offset>length || n+m+1>sizeof(name->scope))
246 return(0);
247 offset++;
248 while (m--)
249 name->scope[n++] = (char)ubuf[offset++];
252 * Watch for malicious loops.
254 if (loop_count++ == 10)
255 return 0;
257 name->scope[n++] = 0;
259 return(ret);
262 /****************************************************************************
263 Put a netbios name, padding(s) and a name type into a 16 character buffer.
264 name is already in DOS charset.
265 [15 bytes name + padding][1 byte name type].
266 ****************************************************************************/
268 static void put_name(char *dest, const char *name, int pad, unsigned int name_type)
270 size_t len = strlen(name);
272 memcpy(dest, name, (len < MAX_NETBIOSNAME_LEN) ? len : MAX_NETBIOSNAME_LEN - 1);
273 if (len < MAX_NETBIOSNAME_LEN - 1) {
274 memset(dest + len, pad, MAX_NETBIOSNAME_LEN - 1 - len);
276 dest[MAX_NETBIOSNAME_LEN - 1] = name_type;
279 /*******************************************************************
280 Put a compressed nmb name into a buffer. Return the length of the
281 compressed name.
283 Compressed names are really weird. The "compression" doubles the
284 size. The idea is that it also means that compressed names conform
285 to the doman name system. See RFC1002.
286 ******************************************************************/
288 static int put_nmb_name(char *buf,int offset,struct nmb_name *name)
290 int ret,m;
291 nstring buf1;
292 char *p;
294 if (strcmp(name->name,"*") == 0) {
295 /* special case for wildcard name */
296 put_name(buf1, "*", '\0', name->name_type);
297 } else {
298 put_name(buf1, name->name, ' ', name->name_type);
301 buf[offset] = 0x20;
303 ret = 34;
305 for (m=0;m<MAX_NETBIOSNAME_LEN;m++) {
306 buf[offset+1+2*m] = 'A' + ((buf1[m]>>4)&0xF);
307 buf[offset+2+2*m] = 'A' + (buf1[m]&0xF);
309 offset += 33;
311 buf[offset] = 0;
313 if (name->scope[0]) {
314 /* XXXX this scope handling needs testing */
315 ret += strlen(name->scope) + 1;
316 safe_strcpy(&buf[offset+1],name->scope,sizeof(name->scope));
318 p = &buf[offset+1];
319 while ((p = strchr_m(p,'.'))) {
320 buf[offset] = PTR_DIFF(p,&buf[offset+1]);
321 offset += (buf[offset] + 1);
322 p = &buf[offset+1];
324 buf[offset] = strlen(&buf[offset+1]);
327 return(ret);
330 /*******************************************************************
331 Useful for debugging messages.
332 ******************************************************************/
334 char *nmb_namestr(struct nmb_name *n)
336 static int i=0;
337 static fstring ret[4];
338 fstring name;
339 char *p = ret[i];
341 pull_ascii_fstring(name, n->name);
342 if (!n->scope[0])
343 slprintf(p,sizeof(fstring)-1, "%s<%02x>",name,n->name_type);
344 else
345 slprintf(p,sizeof(fstring)-1, "%s<%02x>.%s",name,n->name_type,n->scope);
347 i = (i+1)%4;
348 return(p);
351 /*******************************************************************
352 Allocate and parse some resource records.
353 ******************************************************************/
355 static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length,
356 struct res_rec **recs, int count)
358 int i;
360 *recs = SMB_MALLOC_ARRAY(struct res_rec, count);
361 if (!*recs)
362 return(False);
364 memset((char *)*recs,'\0',sizeof(**recs)*count);
366 for (i=0;i<count;i++) {
367 int l = parse_nmb_name(inbuf,*offset,length,&(*recs)[i].rr_name);
368 (*offset) += l;
369 if (!l || (*offset)+10 > length) {
370 SAFE_FREE(*recs);
371 return(False);
373 (*recs)[i].rr_type = RSVAL(inbuf,(*offset));
374 (*recs)[i].rr_class = RSVAL(inbuf,(*offset)+2);
375 (*recs)[i].ttl = RIVAL(inbuf,(*offset)+4);
376 (*recs)[i].rdlength = RSVAL(inbuf,(*offset)+8);
377 (*offset) += 10;
378 if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) ||
379 (*offset)+(*recs)[i].rdlength > length) {
380 SAFE_FREE(*recs);
381 return(False);
383 memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength);
384 (*offset) += (*recs)[i].rdlength;
386 return(True);
389 /*******************************************************************
390 Put a resource record into a packet.
391 ******************************************************************/
393 static int put_res_rec(char *buf,int offset,struct res_rec *recs,int count)
395 int ret=0;
396 int i;
398 for (i=0;i<count;i++) {
399 int l = put_nmb_name(buf,offset,&recs[i].rr_name);
400 offset += l;
401 ret += l;
402 RSSVAL(buf,offset,recs[i].rr_type);
403 RSSVAL(buf,offset+2,recs[i].rr_class);
404 RSIVAL(buf,offset+4,recs[i].ttl);
405 RSSVAL(buf,offset+8,recs[i].rdlength);
406 memcpy(buf+offset+10,recs[i].rdata,recs[i].rdlength);
407 offset += 10+recs[i].rdlength;
408 ret += 10+recs[i].rdlength;
411 return(ret);
414 /*******************************************************************
415 Put a compressed name pointer record into a packet.
416 ******************************************************************/
418 static int put_compressed_name_ptr(unsigned char *buf,int offset,struct res_rec *rec,int ptr_offset)
420 int ret=0;
421 buf[offset] = (0xC0 | ((ptr_offset >> 8) & 0xFF));
422 buf[offset+1] = (ptr_offset & 0xFF);
423 offset += 2;
424 ret += 2;
425 RSSVAL(buf,offset,rec->rr_type);
426 RSSVAL(buf,offset+2,rec->rr_class);
427 RSIVAL(buf,offset+4,rec->ttl);
428 RSSVAL(buf,offset+8,rec->rdlength);
429 memcpy(buf+offset+10,rec->rdata,rec->rdlength);
430 offset += 10+rec->rdlength;
431 ret += 10+rec->rdlength;
433 return(ret);
436 /*******************************************************************
437 Parse a dgram packet. Return False if the packet can't be parsed
438 or is invalid for some reason, True otherwise.
440 This is documented in section 4.4.1 of RFC1002.
441 ******************************************************************/
443 static BOOL parse_dgram(char *inbuf,int length,struct dgram_packet *dgram)
445 int offset;
446 int flags;
448 memset((char *)dgram,'\0',sizeof(*dgram));
450 if (length < 14)
451 return(False);
453 dgram->header.msg_type = CVAL(inbuf,0);
454 flags = CVAL(inbuf,1);
455 dgram->header.flags.node_type = (enum node_type)((flags>>2)&3);
456 if (flags & 1)
457 dgram->header.flags.more = True;
458 if (flags & 2)
459 dgram->header.flags.first = True;
460 dgram->header.dgm_id = RSVAL(inbuf,2);
461 putip((char *)&dgram->header.source_ip,inbuf+4);
462 dgram->header.source_port = RSVAL(inbuf,8);
463 dgram->header.dgm_length = RSVAL(inbuf,10);
464 dgram->header.packet_offset = RSVAL(inbuf,12);
466 offset = 14;
468 if (dgram->header.msg_type == 0x10 ||
469 dgram->header.msg_type == 0x11 ||
470 dgram->header.msg_type == 0x12) {
471 offset += parse_nmb_name(inbuf,offset,length,&dgram->source_name);
472 offset += parse_nmb_name(inbuf,offset,length,&dgram->dest_name);
475 if (offset >= length || (length-offset > sizeof(dgram->data)))
476 return(False);
478 dgram->datasize = length-offset;
479 memcpy(dgram->data,inbuf+offset,dgram->datasize);
481 /* Paranioa. Ensure the last 2 bytes in the dgram buffer are
482 zero. This should be true anyway, just enforce it for paranioa sake. JRA. */
483 SMB_ASSERT(dgram->datasize <= (sizeof(dgram->data)-2));
484 memset(&dgram->data[sizeof(dgram->data)-2], '\0', 2);
486 return(True);
489 /*******************************************************************
490 Parse a nmb packet. Return False if the packet can't be parsed
491 or is invalid for some reason, True otherwise.
492 ******************************************************************/
494 static BOOL parse_nmb(char *inbuf,int length,struct nmb_packet *nmb)
496 int nm_flags,offset;
498 memset((char *)nmb,'\0',sizeof(*nmb));
500 if (length < 12)
501 return(False);
503 /* parse the header */
504 nmb->header.name_trn_id = RSVAL(inbuf,0);
506 DEBUG(10,("parse_nmb: packet id = %d\n", nmb->header.name_trn_id));
508 nmb->header.opcode = (CVAL(inbuf,2) >> 3) & 0xF;
509 nmb->header.response = ((CVAL(inbuf,2)>>7)&1)?True:False;
510 nm_flags = ((CVAL(inbuf,2) & 0x7) << 4) + (CVAL(inbuf,3)>>4);
511 nmb->header.nm_flags.bcast = (nm_flags&1)?True:False;
512 nmb->header.nm_flags.recursion_available = (nm_flags&8)?True:False;
513 nmb->header.nm_flags.recursion_desired = (nm_flags&0x10)?True:False;
514 nmb->header.nm_flags.trunc = (nm_flags&0x20)?True:False;
515 nmb->header.nm_flags.authoritative = (nm_flags&0x40)?True:False;
516 nmb->header.rcode = CVAL(inbuf,3) & 0xF;
517 nmb->header.qdcount = RSVAL(inbuf,4);
518 nmb->header.ancount = RSVAL(inbuf,6);
519 nmb->header.nscount = RSVAL(inbuf,8);
520 nmb->header.arcount = RSVAL(inbuf,10);
522 if (nmb->header.qdcount) {
523 offset = parse_nmb_name(inbuf,12,length,&nmb->question.question_name);
524 if (!offset)
525 return(False);
527 if (length - (12+offset) < 4)
528 return(False);
529 nmb->question.question_type = RSVAL(inbuf,12+offset);
530 nmb->question.question_class = RSVAL(inbuf,12+offset+2);
532 offset += 12+4;
533 } else {
534 offset = 12;
537 /* and any resource records */
538 if (nmb->header.ancount && !parse_alloc_res_rec(inbuf,&offset,length,&nmb->answers,
539 nmb->header.ancount))
540 return(False);
542 if (nmb->header.nscount && !parse_alloc_res_rec(inbuf,&offset,length,&nmb->nsrecs,
543 nmb->header.nscount))
544 return(False);
546 if (nmb->header.arcount && !parse_alloc_res_rec(inbuf,&offset,length,&nmb->additional,
547 nmb->header.arcount))
548 return(False);
550 return(True);
553 /*******************************************************************
554 'Copy constructor' for an nmb packet.
555 ******************************************************************/
557 static struct packet_struct *copy_nmb_packet(struct packet_struct *packet)
559 struct nmb_packet *nmb;
560 struct nmb_packet *copy_nmb;
561 struct packet_struct *pkt_copy;
563 if(( pkt_copy = SMB_MALLOC_P(struct packet_struct)) == NULL) {
564 DEBUG(0,("copy_nmb_packet: malloc fail.\n"));
565 return NULL;
568 /* Structure copy of entire thing. */
570 *pkt_copy = *packet;
572 /* Ensure this copy is not locked. */
573 pkt_copy->locked = False;
575 /* Ensure this copy has no resource records. */
576 nmb = &packet->packet.nmb;
577 copy_nmb = &pkt_copy->packet.nmb;
579 copy_nmb->answers = NULL;
580 copy_nmb->nsrecs = NULL;
581 copy_nmb->additional = NULL;
583 /* Now copy any resource records. */
585 if (nmb->answers) {
586 if((copy_nmb->answers = SMB_MALLOC_ARRAY(struct res_rec,nmb->header.ancount)) == NULL)
587 goto free_and_exit;
588 memcpy((char *)copy_nmb->answers, (char *)nmb->answers,
589 nmb->header.ancount * sizeof(struct res_rec));
591 if (nmb->nsrecs) {
592 if((copy_nmb->nsrecs = SMB_MALLOC_ARRAY(struct res_rec, nmb->header.nscount)) == NULL)
593 goto free_and_exit;
594 memcpy((char *)copy_nmb->nsrecs, (char *)nmb->nsrecs,
595 nmb->header.nscount * sizeof(struct res_rec));
597 if (nmb->additional) {
598 if((copy_nmb->additional = SMB_MALLOC_ARRAY(struct res_rec, nmb->header.arcount)) == NULL)
599 goto free_and_exit;
600 memcpy((char *)copy_nmb->additional, (char *)nmb->additional,
601 nmb->header.arcount * sizeof(struct res_rec));
604 return pkt_copy;
606 free_and_exit:
608 SAFE_FREE(copy_nmb->answers);
609 SAFE_FREE(copy_nmb->nsrecs);
610 SAFE_FREE(copy_nmb->additional);
611 SAFE_FREE(pkt_copy);
613 DEBUG(0,("copy_nmb_packet: malloc fail in resource records.\n"));
614 return NULL;
617 /*******************************************************************
618 'Copy constructor' for a dgram packet.
619 ******************************************************************/
621 static struct packet_struct *copy_dgram_packet(struct packet_struct *packet)
623 struct packet_struct *pkt_copy;
625 if(( pkt_copy = SMB_MALLOC_P(struct packet_struct)) == NULL) {
626 DEBUG(0,("copy_dgram_packet: malloc fail.\n"));
627 return NULL;
630 /* Structure copy of entire thing. */
632 *pkt_copy = *packet;
634 /* Ensure this copy is not locked. */
635 pkt_copy->locked = False;
637 /* There are no additional pointers in a dgram packet,
638 we are finished. */
639 return pkt_copy;
642 /*******************************************************************
643 'Copy constructor' for a generic packet.
644 ******************************************************************/
646 struct packet_struct *copy_packet(struct packet_struct *packet)
648 if(packet->packet_type == NMB_PACKET)
649 return copy_nmb_packet(packet);
650 else if (packet->packet_type == DGRAM_PACKET)
651 return copy_dgram_packet(packet);
652 return NULL;
655 /*******************************************************************
656 Free up any resources associated with an nmb packet.
657 ******************************************************************/
659 static void free_nmb_packet(struct nmb_packet *nmb)
661 SAFE_FREE(nmb->answers);
662 SAFE_FREE(nmb->nsrecs);
663 SAFE_FREE(nmb->additional);
666 /*******************************************************************
667 Free up any resources associated with a dgram packet.
668 ******************************************************************/
670 static void free_dgram_packet(struct dgram_packet *nmb)
672 /* We have nothing to do for a dgram packet. */
675 /*******************************************************************
676 Free up any resources associated with a packet.
677 ******************************************************************/
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 SAFE_FREE(packet);
691 /*******************************************************************
692 Parse a packet buffer into a packet structure.
693 ******************************************************************/
695 struct packet_struct *parse_packet(char *buf,int length,
696 enum packet_type packet_type)
698 struct packet_struct *p;
699 BOOL ok=False;
701 p = SMB_MALLOC_P(struct packet_struct);
702 if (!p)
703 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 ******************************************************************/
736 struct packet_struct *read_packet(int fd,enum packet_type packet_type)
738 struct packet_struct *packet;
739 char buf[MAX_DGRAM_SIZE];
740 int length;
742 length = read_udp_socket(fd,buf,sizeof(buf));
743 if (length < MIN_DGRAM_SIZE)
744 return(NULL);
746 packet = parse_packet(buf, length, packet_type);
747 if (!packet)
748 return NULL;
750 packet->fd = fd;
752 num_good_receives++;
754 DEBUG(5,("Received a packet of len %d from (%s) port %d\n",
755 length, inet_ntoa(packet->ip), packet->port ) );
757 return(packet);
760 /*******************************************************************
761 Send a udp packet on a already open socket.
762 ******************************************************************/
764 static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port)
766 BOOL ret = False;
767 int i;
768 struct sockaddr_in sock_out;
770 /* set the address and port */
771 memset((char *)&sock_out,'\0',sizeof(sock_out));
772 putip((char *)&sock_out.sin_addr,(char *)&ip);
773 sock_out.sin_port = htons( port );
774 sock_out.sin_family = AF_INET;
776 DEBUG( 5, ( "Sending a packet of len %d to (%s) on port %d\n",
777 len, inet_ntoa(ip), port ) );
780 * Patch to fix asynch error notifications from Linux kernel.
783 for (i = 0; i < 5; i++) {
784 ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out, sizeof(sock_out)) >= 0);
785 if (ret || errno != ECONNREFUSED)
786 break;
789 if (!ret)
790 DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n",
791 inet_ntoa(ip),port,strerror(errno)));
793 if (ret)
794 num_good_sends++;
796 return(ret);
799 /*******************************************************************
800 Build a dgram packet ready for sending.
802 XXXX This currently doesn't handle packets too big for one
803 datagram. It should split them and use the packet_offset, more and
804 first flags to handle the fragmentation. Yuck.
806 [...but it isn't clear that we would ever need to send a
807 a fragmented NBT Datagram. The IP layer does its own
808 fragmentation to ensure that messages can fit into the path
809 MTU. It *is* important to be able to receive and rebuild
810 fragmented NBT datagrams, just in case someone out there
811 really has implemented this 'feature'. crh -)------ ]
813 ******************************************************************/
815 static int build_dgram(char *buf,struct packet_struct *p)
817 struct dgram_packet *dgram = &p->packet.dgram;
818 unsigned char *ubuf = (unsigned char *)buf;
819 int offset=0;
821 /* put in the header */
822 ubuf[0] = dgram->header.msg_type;
823 ubuf[1] = (((int)dgram->header.flags.node_type)<<2);
824 if (dgram->header.flags.more)
825 ubuf[1] |= 1;
826 if (dgram->header.flags.first)
827 ubuf[1] |= 2;
828 RSSVAL(ubuf,2,dgram->header.dgm_id);
829 putip(ubuf+4,(char *)&dgram->header.source_ip);
830 RSSVAL(ubuf,8,dgram->header.source_port);
831 RSSVAL(ubuf,12,dgram->header.packet_offset);
833 offset = 14;
835 if (dgram->header.msg_type == 0x10 ||
836 dgram->header.msg_type == 0x11 ||
837 dgram->header.msg_type == 0x12) {
838 offset += put_nmb_name((char *)ubuf,offset,&dgram->source_name);
839 offset += put_nmb_name((char *)ubuf,offset,&dgram->dest_name);
842 memcpy(ubuf+offset,dgram->data,dgram->datasize);
843 offset += dgram->datasize;
845 /* automatically set the dgm_length
846 * NOTE: RFC1002 says the dgm_length does *not*
847 * include the fourteen-byte header. crh
849 dgram->header.dgm_length = (offset - 14);
850 RSSVAL(ubuf,10,dgram->header.dgm_length);
852 return(offset);
855 /*******************************************************************
856 Build a nmb name
857 *******************************************************************/
859 void make_nmb_name( struct nmb_name *n, const char *name, int type)
861 fstring unix_name;
862 memset( (char *)n, '\0', sizeof(struct nmb_name) );
863 fstrcpy(unix_name, name);
864 strupper_m(unix_name);
865 push_ascii(n->name, unix_name, sizeof(n->name), STR_TERMINATE);
866 n->name_type = (unsigned int)type & 0xFF;
867 push_ascii(n->scope, global_scope(), 64, STR_TERMINATE);
870 /*******************************************************************
871 Compare two nmb names
872 ******************************************************************/
874 BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2)
876 return ((n1->name_type == n2->name_type) &&
877 strequal(n1->name ,n2->name ) &&
878 strequal(n1->scope,n2->scope));
881 /*******************************************************************
882 Build a nmb packet ready for sending.
884 XXXX this currently relies on not being passed something that expands
885 to a packet too big for the buffer. Eventually this should be
886 changed to set the trunc bit so the receiver can request the rest
887 via tcp (when that becomes supported)
888 ******************************************************************/
890 static int build_nmb(char *buf,struct packet_struct *p)
892 struct nmb_packet *nmb = &p->packet.nmb;
893 unsigned char *ubuf = (unsigned char *)buf;
894 int offset=0;
896 /* put in the header */
897 RSSVAL(ubuf,offset,nmb->header.name_trn_id);
898 ubuf[offset+2] = (nmb->header.opcode & 0xF) << 3;
899 if (nmb->header.response)
900 ubuf[offset+2] |= (1<<7);
901 if (nmb->header.nm_flags.authoritative &&
902 nmb->header.response)
903 ubuf[offset+2] |= 0x4;
904 if (nmb->header.nm_flags.trunc)
905 ubuf[offset+2] |= 0x2;
906 if (nmb->header.nm_flags.recursion_desired)
907 ubuf[offset+2] |= 0x1;
908 if (nmb->header.nm_flags.recursion_available &&
909 nmb->header.response)
910 ubuf[offset+3] |= 0x80;
911 if (nmb->header.nm_flags.bcast)
912 ubuf[offset+3] |= 0x10;
913 ubuf[offset+3] |= (nmb->header.rcode & 0xF);
915 RSSVAL(ubuf,offset+4,nmb->header.qdcount);
916 RSSVAL(ubuf,offset+6,nmb->header.ancount);
917 RSSVAL(ubuf,offset+8,nmb->header.nscount);
918 RSSVAL(ubuf,offset+10,nmb->header.arcount);
920 offset += 12;
921 if (nmb->header.qdcount) {
922 /* XXXX this doesn't handle a qdcount of > 1 */
923 offset += put_nmb_name((char *)ubuf,offset,&nmb->question.question_name);
924 RSSVAL(ubuf,offset,nmb->question.question_type);
925 RSSVAL(ubuf,offset+2,nmb->question.question_class);
926 offset += 4;
929 if (nmb->header.ancount)
930 offset += put_res_rec((char *)ubuf,offset,nmb->answers,
931 nmb->header.ancount);
933 if (nmb->header.nscount)
934 offset += put_res_rec((char *)ubuf,offset,nmb->nsrecs,
935 nmb->header.nscount);
938 * The spec says we must put compressed name pointers
939 * in the following outgoing packets :
940 * NAME_REGISTRATION_REQUEST, NAME_REFRESH_REQUEST,
941 * NAME_RELEASE_REQUEST.
944 if((nmb->header.response == False) &&
945 ((nmb->header.opcode == NMB_NAME_REG_OPCODE) ||
946 (nmb->header.opcode == NMB_NAME_RELEASE_OPCODE) ||
947 (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_8) ||
948 (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_9) ||
949 (nmb->header.opcode == NMB_NAME_MULTIHOMED_REG_OPCODE)) &&
950 (nmb->header.arcount == 1)) {
952 offset += put_compressed_name_ptr(ubuf,offset,nmb->additional,12);
954 } else if (nmb->header.arcount) {
955 offset += put_res_rec((char *)ubuf,offset,nmb->additional,
956 nmb->header.arcount);
958 return(offset);
961 /*******************************************************************
962 Linearise a packet.
963 ******************************************************************/
965 int build_packet(char *buf, struct packet_struct *p)
967 int len = 0;
969 switch (p->packet_type) {
970 case NMB_PACKET:
971 len = build_nmb(buf,p);
972 break;
974 case DGRAM_PACKET:
975 len = build_dgram(buf,p);
976 break;
979 return len;
982 /*******************************************************************
983 Send a packet_struct.
984 ******************************************************************/
986 BOOL send_packet(struct packet_struct *p)
988 char buf[1024];
989 int len=0;
991 memset(buf,'\0',sizeof(buf));
993 len = build_packet(buf, p);
995 if (!len)
996 return(False);
998 return(send_udp(p->fd,buf,len,p->ip,p->port));
1001 /****************************************************************************
1002 Receive a packet with timeout on a open UDP filedescriptor.
1003 The timeout is in milliseconds
1004 ***************************************************************************/
1006 struct packet_struct *receive_packet(int fd,enum packet_type type,int t)
1008 fd_set fds;
1009 struct timeval timeout;
1010 int ret;
1012 FD_ZERO(&fds);
1013 FD_SET(fd,&fds);
1014 timeout.tv_sec = t/1000;
1015 timeout.tv_usec = 1000*(t%1000);
1017 if ((ret = sys_select_intr(fd+1,&fds,NULL,NULL,&timeout)) == -1) {
1018 /* errno should be EBADF or EINVAL. */
1019 DEBUG(0,("select returned -1, errno = %s (%d)\n", strerror(errno), errno));
1020 return NULL;
1023 if (ret == 0) /* timeout */
1024 return NULL;
1026 if (FD_ISSET(fd,&fds))
1027 return(read_packet(fd,type));
1029 return(NULL);
1032 /****************************************************************************
1033 Receive a UDP/137 packet either via UDP or from the unexpected packet
1034 queue. The packet must be a reply packet and have the specified trn_id.
1035 The timeout is in milliseconds.
1036 ***************************************************************************/
1038 struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id)
1040 struct packet_struct *p;
1042 p = receive_packet(fd, NMB_PACKET, t);
1044 if (p && p->packet.nmb.header.response &&
1045 p->packet.nmb.header.name_trn_id == trn_id) {
1046 return p;
1048 if (p)
1049 free_packet(p);
1051 /* try the unexpected packet queue */
1052 return receive_unexpected(NMB_PACKET, trn_id, NULL);
1055 /****************************************************************************
1056 Receive a UDP/138 packet either via UDP or from the unexpected packet
1057 queue. The packet must be a reply packet and have the specified mailslot name
1058 The timeout is in milliseconds.
1059 ***************************************************************************/
1061 struct packet_struct *receive_dgram_packet(int fd, int t, const char *mailslot_name)
1063 struct packet_struct *p;
1065 p = receive_packet(fd, DGRAM_PACKET, t);
1067 if (p && match_mailslot_name(p, mailslot_name)) {
1068 return p;
1070 if (p)
1071 free_packet(p);
1073 /* try the unexpected packet queue */
1074 return receive_unexpected(DGRAM_PACKET, 0, mailslot_name);
1077 /****************************************************************************
1078 See if a datagram has the right mailslot name.
1079 ***************************************************************************/
1081 BOOL match_mailslot_name(struct packet_struct *p, const char *mailslot_name)
1083 struct dgram_packet *dgram = &p->packet.dgram;
1084 char *buf;
1086 buf = &dgram->data[0];
1087 buf -= 4;
1089 buf = smb_buf(buf);
1091 if (memcmp(buf, mailslot_name, strlen(mailslot_name)+1) == 0) {
1092 return True;
1095 return False;
1098 /****************************************************************************
1099 Return the number of bits that match between two 4 character buffers
1100 ***************************************************************************/
1102 int matching_quad_bits(unsigned char *p1, unsigned char *p2)
1104 int i, j, ret = 0;
1105 for (i=0; i<4; i++) {
1106 if (p1[i] != p2[i])
1107 break;
1108 ret += 8;
1111 if (i==4)
1112 return ret;
1114 for (j=0; j<8; j++) {
1115 if ((p1[i] & (1<<(7-j))) != (p2[i] & (1<<(7-j))))
1116 break;
1117 ret++;
1120 return ret;
1123 static unsigned char sort_ip[4];
1125 /****************************************************************************
1126 Compare two query reply records.
1127 ***************************************************************************/
1129 static int name_query_comp(unsigned char *p1, unsigned char *p2)
1131 return matching_quad_bits(p2+2, sort_ip) - matching_quad_bits(p1+2, sort_ip);
1134 /****************************************************************************
1135 Sort a set of 6 byte name query response records so that the IPs that
1136 have the most leading bits in common with the specified address come first.
1137 ***************************************************************************/
1139 void sort_query_replies(char *data, int n, struct in_addr ip)
1141 if (n <= 1)
1142 return;
1144 putip(sort_ip, (char *)&ip);
1146 qsort(data, n, 6, QSORT_CAST name_query_comp);
1149 /*******************************************************************
1150 Convert, possibly using a stupid microsoft-ism which has destroyed
1151 the transport independence of netbios (for CIFS vendors that usually
1152 use the Win95-type methods, not for NT to NT communication, which uses
1153 DCE/RPC and therefore full-length unicode strings...) a dns name into
1154 a netbios name.
1156 The netbios name (NOT necessarily null-terminated) is truncated to 15
1157 characters.
1159 ******************************************************************/
1161 char *dns_to_netbios_name(const char *dns_name)
1163 static nstring netbios_name;
1164 int i;
1165 StrnCpy(netbios_name, dns_name, MAX_NETBIOSNAME_LEN-1);
1166 netbios_name[15] = 0;
1168 /* ok. this is because of a stupid microsoft-ism. if the called host
1169 name contains a '.', microsoft clients expect you to truncate the
1170 netbios name up to and including the '.' this even applies, by
1171 mistake, to workgroup (domain) names, which is _really_ daft.
1173 for (i = 0; i < 15; i++) {
1174 if (netbios_name[i] == '.') {
1175 netbios_name[i] = 0;
1176 break;
1180 return netbios_name;
1183 /****************************************************************************
1184 Interpret the weird netbios "name" into a unix fstring. Return the name type.
1185 ****************************************************************************/
1187 static int name_interpret(char *in, fstring name)
1189 int ret;
1190 int len = (*in++) / 2;
1191 fstring out_string;
1192 char *out = out_string;
1194 *out=0;
1196 if (len > 30 || len<1)
1197 return(0);
1199 while (len--) {
1200 if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
1201 *out = 0;
1202 return(0);
1204 *out = ((in[0]-'A')<<4) + (in[1]-'A');
1205 in += 2;
1206 out++;
1208 ret = out[-1];
1209 out[-1] = 0;
1211 #ifdef NETBIOS_SCOPE
1212 /* Handle any scope names */
1213 while(*in) {
1214 *out++ = '.'; /* Scope names are separated by periods */
1215 len = *(unsigned char *)in++;
1216 StrnCpy(out, in, len);
1217 out += len;
1218 *out=0;
1219 in += len;
1221 #endif
1222 pull_ascii_fstring(name, out_string);
1224 return(ret);
1227 /****************************************************************************
1228 Mangle a name into netbios format.
1229 Note: <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
1230 ****************************************************************************/
1232 int name_mangle( char *In, char *Out, char name_type )
1234 int i;
1235 int len;
1236 nstring buf;
1237 char *p = Out;
1239 /* Safely copy the input string, In, into buf[]. */
1240 if (strcmp(In,"*") == 0)
1241 put_name(buf, "*", '\0', 0x00);
1242 else {
1243 /* We use an fstring here as mb dos names can expend x3 when
1244 going to utf8. */
1245 fstring buf_unix;
1246 nstring buf_dos;
1248 pull_ascii_fstring(buf_unix, In);
1249 strupper_m(buf_unix);
1251 push_ascii_nstring(buf_dos, buf_unix);
1252 put_name(buf, buf_dos, ' ', name_type);
1255 /* Place the length of the first field into the output buffer. */
1256 p[0] = 32;
1257 p++;
1259 /* Now convert the name to the rfc1001/1002 format. */
1260 for( i = 0; i < MAX_NETBIOSNAME_LEN; i++ ) {
1261 p[i*2] = ( (buf[i] >> 4) & 0x000F ) + 'A';
1262 p[(i*2)+1] = (buf[i] & 0x000F) + 'A';
1264 p += 32;
1265 p[0] = '\0';
1267 /* Add the scope string. */
1268 for( i = 0, len = 0; *(global_scope()) != '\0'; i++, len++ ) {
1269 switch( (global_scope())[i] ) {
1270 case '\0':
1271 p[0] = len;
1272 if( len > 0 )
1273 p[len+1] = 0;
1274 return( name_len(Out) );
1275 case '.':
1276 p[0] = len;
1277 p += (len + 1);
1278 len = -1;
1279 break;
1280 default:
1281 p[len+1] = (global_scope())[i];
1282 break;
1286 return( name_len(Out) );
1289 /****************************************************************************
1290 Find a pointer to a netbios name.
1291 ****************************************************************************/
1293 static char *name_ptr(char *buf,int ofs)
1295 unsigned char c = *(unsigned char *)(buf+ofs);
1297 if ((c & 0xC0) == 0xC0) {
1298 uint16 l = RSVAL(buf, ofs) & 0x3FFF;
1299 DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
1300 return(buf + l);
1301 } else {
1302 return(buf+ofs);
1306 /****************************************************************************
1307 Extract a netbios name from a buf (into a unix string) return name type.
1308 ****************************************************************************/
1310 int name_extract(char *buf,int ofs, fstring name)
1312 char *p = name_ptr(buf,ofs);
1313 int d = PTR_DIFF(p,buf+ofs);
1315 name[0] = '\0';
1316 if (d < -50 || d > 50)
1317 return(0);
1318 return(name_interpret(p,name));
1321 /****************************************************************************
1322 Return the total storage length of a mangled name.
1323 ****************************************************************************/
1325 int name_len(char *s1)
1327 /* NOTE: this argument _must_ be unsigned */
1328 unsigned char *s = (unsigned char *)s1;
1329 int len;
1331 /* If the two high bits of the byte are set, return 2. */
1332 if (0xC0 == (*s & 0xC0))
1333 return(2);
1335 /* Add up the length bytes. */
1336 for (len = 1; (*s); s += (*s) + 1) {
1337 len += *s + 1;
1338 SMB_ASSERT(len < 80);
1341 return(len);