s3:net ads join: improve status evaluation for call to net_update_dns()
[Samba/bb.git] / source3 / libsmb / nmblib.c
blob767ff81476e882140172a014b7699448d51ec975
1 /*
2 Unix SMB/CIFS implementation.
3 NBT netbios library routines
4 Copyright (C) Andrew Tridgell 1994-1998
5 Copyright (C) Jeremy Allison 2007
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 3 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, see <http://www.gnu.org/licenses/>.
22 #include "includes.h"
23 #include "libsmb/nmblib.h"
25 static const struct opcode_names {
26 const char *nmb_opcode_name;
27 int opcode;
28 } nmb_header_opcode_names[] = {
29 {"Query", 0 },
30 {"Registration", 5 },
31 {"Release", 6 },
32 {"WACK", 7 },
33 {"Refresh", 8 },
34 {"Refresh(altcode)", 9 },
35 {"Multi-homed Registration", 15 },
36 {0, -1 }
39 /****************************************************************************
40 Lookup a nmb opcode name.
41 ****************************************************************************/
43 static const char *lookup_opcode_name( int opcode )
45 const struct opcode_names *op_namep;
46 int i;
48 for(i = 0; nmb_header_opcode_names[i].nmb_opcode_name != 0; i++) {
49 op_namep = &nmb_header_opcode_names[i];
50 if(opcode == op_namep->opcode)
51 return op_namep->nmb_opcode_name;
53 return "<unknown opcode>";
56 /****************************************************************************
57 Print out a res_rec structure.
58 ****************************************************************************/
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+= MAX_NETBIOSNAME_LEN) {
75 DEBUGADD(4, (" %s %3x char ", hdr, i));
77 for (j = 0; j < MAX_NETBIOSNAME_LEN; j++) {
78 unsigned char x = res->rdata[i+j];
79 if (x < 32 || x > 127)
80 x = '.';
82 if (i+j >= res->rdlength)
83 break;
84 DEBUGADD(4, ("%c", x));
87 DEBUGADD(4, (" hex "));
89 for (j = 0; j < MAX_NETBIOSNAME_LEN; j++) {
90 if (i+j >= res->rdlength)
91 break;
92 DEBUGADD(4, ("%02X", (unsigned char)res->rdata[i+j]));
95 DEBUGADD(4, ("\n"));
99 /****************************************************************************
100 Process a nmb packet.
101 ****************************************************************************/
103 void debug_nmb_packet(struct packet_struct *p)
105 struct nmb_packet *nmb = &p->packet.nmb;
107 if( DEBUGLVL( 4 ) ) {
108 dbgtext( "nmb packet from %s(%d) header: id=%d "
109 "opcode=%s(%d) response=%s\n",
110 inet_ntoa(p->ip), p->port,
111 nmb->header.name_trn_id,
112 lookup_opcode_name(nmb->header.opcode),
113 nmb->header.opcode,
114 BOOLSTR(nmb->header.response) );
115 dbgtext( " header: flags: bcast=%s rec_avail=%s "
116 "rec_des=%s trunc=%s auth=%s\n",
117 BOOLSTR(nmb->header.nm_flags.bcast),
118 BOOLSTR(nmb->header.nm_flags.recursion_available),
119 BOOLSTR(nmb->header.nm_flags.recursion_desired),
120 BOOLSTR(nmb->header.nm_flags.trunc),
121 BOOLSTR(nmb->header.nm_flags.authoritative) );
122 dbgtext( " header: rcode=%d qdcount=%d ancount=%d "
123 "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) {
132 DEBUGADD( 4, ( " question: q_name=%s q_type=%d q_class=%d\n",
133 nmb_namestr(&nmb->question.question_name),
134 nmb->question.question_type,
135 nmb->question.question_class) );
138 if (nmb->answers && nmb->header.ancount) {
139 debug_nmb_res_rec(nmb->answers,"answers");
141 if (nmb->nsrecs && nmb->header.nscount) {
142 debug_nmb_res_rec(nmb->nsrecs,"nsrecs");
144 if (nmb->additional && nmb->header.arcount) {
145 debug_nmb_res_rec(nmb->additional,"additional");
149 /*******************************************************************
150 Handle "compressed" name pointers.
151 ******************************************************************/
153 static bool handle_name_ptrs(unsigned char *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)
160 (*ret) += 2;
161 (*got_pointer)=True;
162 (*offset) = ((ubuf[*offset] & ~0xC0)<<8) | ubuf[(*offset)+1];
163 if (loop_count++ == 10 ||
164 (*offset) < 0 || (*offset)>(length-2)) {
165 return False;
168 return True;
171 /*******************************************************************
172 Parse a nmb name from "compressed" format to something readable
173 return the space taken by the name, or 0 if the name is invalid
174 ******************************************************************/
176 static int parse_nmb_name(char *inbuf,int ofs,int length, struct nmb_name *name)
178 int m,n=0;
179 unsigned char *ubuf = (unsigned char *)inbuf;
180 int ret = 0;
181 bool got_pointer=False;
182 int loop_count=0;
183 int offset = ofs;
185 if (length - offset < 2)
186 return(0);
188 /* handle initial name pointers */
189 if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret))
190 return(0);
192 m = ubuf[offset];
194 if (!m)
195 return(0);
196 if ((m & 0xC0) || offset+m+2 > length)
197 return(0);
199 memset((char *)name,'\0',sizeof(*name));
201 /* the "compressed" part */
202 if (!got_pointer)
203 ret += m + 2;
204 offset++;
205 while (m > 0) {
206 unsigned char c1,c2;
207 c1 = ubuf[offset++]-'A';
208 c2 = ubuf[offset++]-'A';
209 if ((c1 & 0xF0) || (c2 & 0xF0) || (n > sizeof(name->name)-1))
210 return(0);
211 name->name[n++] = (c1<<4) | c2;
212 m -= 2;
214 name->name[n] = 0;
216 if (n==MAX_NETBIOSNAME_LEN) {
217 /* parse out the name type, its always
218 * 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 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) ?
273 len : MAX_NETBIOSNAME_LEN - 1);
274 if (len < MAX_NETBIOSNAME_LEN - 1) {
275 memset(dest + len, pad, MAX_NETBIOSNAME_LEN - 1 - len);
277 dest[MAX_NETBIOSNAME_LEN - 1] = name_type;
280 /*******************************************************************
281 Put a compressed nmb name into a buffer. Return the length of the
282 compressed name.
284 Compressed names are really weird. The "compression" doubles the
285 size. The idea is that it also means that compressed names conform
286 to the doman name system. See RFC1002.
288 If buf == NULL this is a length calculation.
289 ******************************************************************/
291 static int put_nmb_name(char *buf, size_t buflen, int offset,struct nmb_name *name)
293 int ret,m;
294 nstring buf1;
295 char *p;
297 if (strcmp(name->name,"*") == 0) {
298 /* special case for wildcard name */
299 put_name(buf1, "*", '\0', name->name_type);
300 } else {
301 put_name(buf1, name->name, ' ', name->name_type);
304 if (buf) {
305 if (offset >= buflen) {
306 return 0;
308 buf[offset] = 0x20;
311 ret = 34;
313 for (m=0;m<MAX_NETBIOSNAME_LEN;m++) {
314 if (buf) {
315 if (offset+2+2*m >= buflen) {
316 return 0;
318 buf[offset+1+2*m] = 'A' + ((buf1[m]>>4)&0xF);
319 buf[offset+2+2*m] = 'A' + (buf1[m]&0xF);
322 offset += 33;
324 if (buf) {
325 if (offset >= buflen) {
326 return 0;
328 buf[offset] = 0;
331 if (name->scope[0]) {
332 /* XXXX this scope handling needs testing */
333 size_t scopenamelen = strlen(name->scope) + 1;
334 ret += scopenamelen;
335 if (buf) {
336 if (offset+1+scopenamelen >= buflen) {
337 return 0;
339 strlcpy(&buf[offset+1],name->scope,
340 buflen - (offset+1));
342 p = &buf[offset+1];
343 while ((p = strchr_m(p,'.'))) {
344 buf[offset] = PTR_DIFF(p,&buf[offset+1]);
345 offset += (buf[offset] + 1);
346 if (offset+1 >= buflen) {
347 return 0;
349 p = &buf[offset+1];
351 buf[offset] = strlen(&buf[offset+1]);
355 return ret;
358 /*******************************************************************
359 Useful for debugging messages.
360 ******************************************************************/
362 char *nmb_namestr(const struct nmb_name *n)
364 fstring name;
365 char *result;
367 pull_ascii_fstring(name, n->name);
368 if (!n->scope[0])
369 result = talloc_asprintf(talloc_tos(), "%s<%02x>", name,
370 n->name_type);
371 else
372 result = talloc_asprintf(talloc_tos(), "%s<%02x>.%s", name,
373 n->name_type, n->scope);
375 SMB_ASSERT(result != NULL);
376 return result;
379 /*******************************************************************
380 Allocate and parse some resource records.
381 ******************************************************************/
383 static bool parse_alloc_res_rec(char *inbuf,int *offset,int length,
384 struct res_rec **recs, int count)
386 int i;
388 *recs = SMB_MALLOC_ARRAY(struct res_rec, count);
389 if (!*recs)
390 return(False);
392 memset((char *)*recs,'\0',sizeof(**recs)*count);
394 for (i=0;i<count;i++) {
395 int l = parse_nmb_name(inbuf,*offset,length,
396 &(*recs)[i].rr_name);
397 (*offset) += l;
398 if (!l || (*offset)+10 > length) {
399 SAFE_FREE(*recs);
400 return(False);
402 (*recs)[i].rr_type = RSVAL(inbuf,(*offset));
403 (*recs)[i].rr_class = RSVAL(inbuf,(*offset)+2);
404 (*recs)[i].ttl = RIVAL(inbuf,(*offset)+4);
405 (*recs)[i].rdlength = RSVAL(inbuf,(*offset)+8);
406 (*offset) += 10;
407 if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) ||
408 (*offset)+(*recs)[i].rdlength > length) {
409 SAFE_FREE(*recs);
410 return(False);
412 memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength);
413 (*offset) += (*recs)[i].rdlength;
415 return(True);
418 /*******************************************************************
419 Put a resource record into a packet.
420 If buf == NULL this is a length calculation.
421 ******************************************************************/
423 static int put_res_rec(char *buf, size_t buflen, int offset,struct res_rec *recs,int count)
425 int ret=0;
426 int i;
428 for (i=0;i<count;i++) {
429 int l = put_nmb_name(buf,buflen,offset,&recs[i].rr_name);
430 offset += l;
431 ret += l;
432 if (buf) {
433 RSSVAL(buf,offset,recs[i].rr_type);
434 RSSVAL(buf,offset+2,recs[i].rr_class);
435 RSIVAL(buf,offset+4,recs[i].ttl);
436 RSSVAL(buf,offset+8,recs[i].rdlength);
437 memcpy(buf+offset+10,recs[i].rdata,recs[i].rdlength);
439 offset += 10+recs[i].rdlength;
440 ret += 10+recs[i].rdlength;
443 return ret;
446 /*******************************************************************
447 Put a compressed name pointer record into a packet.
448 If buf == NULL this is a length calculation.
449 ******************************************************************/
451 static int put_compressed_name_ptr(unsigned char *buf,
452 int offset,
453 struct res_rec *rec,
454 int ptr_offset)
456 int ret=0;
457 if (buf) {
458 buf[offset] = (0xC0 | ((ptr_offset >> 8) & 0xFF));
459 buf[offset+1] = (ptr_offset & 0xFF);
461 offset += 2;
462 ret += 2;
463 if (buf) {
464 RSSVAL(buf,offset,rec->rr_type);
465 RSSVAL(buf,offset+2,rec->rr_class);
466 RSIVAL(buf,offset+4,rec->ttl);
467 RSSVAL(buf,offset+8,rec->rdlength);
468 memcpy(buf+offset+10,rec->rdata,rec->rdlength);
470 offset += 10+rec->rdlength;
471 ret += 10+rec->rdlength;
473 return ret;
476 /*******************************************************************
477 Parse a dgram packet. Return False if the packet can't be parsed
478 or is invalid for some reason, True otherwise.
480 This is documented in section 4.4.1 of RFC1002.
481 ******************************************************************/
483 static bool parse_dgram(char *inbuf,int length,struct dgram_packet *dgram)
485 int offset;
486 int flags;
488 memset((char *)dgram,'\0',sizeof(*dgram));
490 if (length < 14)
491 return(False);
493 dgram->header.msg_type = CVAL(inbuf,0);
494 flags = CVAL(inbuf,1);
495 dgram->header.flags.node_type = (enum node_type)((flags>>2)&3);
496 if (flags & 1)
497 dgram->header.flags.more = True;
498 if (flags & 2)
499 dgram->header.flags.first = True;
500 dgram->header.dgm_id = RSVAL(inbuf,2);
501 putip((char *)&dgram->header.source_ip,inbuf+4);
502 dgram->header.source_port = RSVAL(inbuf,8);
503 dgram->header.dgm_length = RSVAL(inbuf,10);
504 dgram->header.packet_offset = RSVAL(inbuf,12);
506 offset = 14;
508 if (dgram->header.msg_type == 0x10 ||
509 dgram->header.msg_type == 0x11 ||
510 dgram->header.msg_type == 0x12) {
511 offset += parse_nmb_name(inbuf,offset,length,
512 &dgram->source_name);
513 offset += parse_nmb_name(inbuf,offset,length,
514 &dgram->dest_name);
517 if (offset >= length || (length-offset > sizeof(dgram->data)))
518 return(False);
520 dgram->datasize = length-offset;
521 memcpy(dgram->data,inbuf+offset,dgram->datasize);
523 /* Paranioa. Ensure the last 2 bytes in the dgram buffer are
524 zero. This should be true anyway, just enforce it for
525 paranioa sake. JRA. */
526 SMB_ASSERT(dgram->datasize <= (sizeof(dgram->data)-2));
527 memset(&dgram->data[sizeof(dgram->data)-2], '\0', 2);
529 return(True);
532 /*******************************************************************
533 Parse a nmb packet. Return False if the packet can't be parsed
534 or is invalid for some reason, True otherwise.
535 ******************************************************************/
537 static bool parse_nmb(char *inbuf,int length,struct nmb_packet *nmb)
539 int nm_flags,offset;
541 memset((char *)nmb,'\0',sizeof(*nmb));
543 if (length < 12)
544 return(False);
546 /* parse the header */
547 nmb->header.name_trn_id = RSVAL(inbuf,0);
549 DEBUG(10,("parse_nmb: packet id = %d\n", nmb->header.name_trn_id));
551 nmb->header.opcode = (CVAL(inbuf,2) >> 3) & 0xF;
552 nmb->header.response = ((CVAL(inbuf,2)>>7)&1)?True:False;
553 nm_flags = ((CVAL(inbuf,2) & 0x7) << 4) + (CVAL(inbuf,3)>>4);
554 nmb->header.nm_flags.bcast = (nm_flags&1)?True:False;
555 nmb->header.nm_flags.recursion_available = (nm_flags&8)?True:False;
556 nmb->header.nm_flags.recursion_desired = (nm_flags&0x10)?True:False;
557 nmb->header.nm_flags.trunc = (nm_flags&0x20)?True:False;
558 nmb->header.nm_flags.authoritative = (nm_flags&0x40)?True:False;
559 nmb->header.rcode = CVAL(inbuf,3) & 0xF;
560 nmb->header.qdcount = RSVAL(inbuf,4);
561 nmb->header.ancount = RSVAL(inbuf,6);
562 nmb->header.nscount = RSVAL(inbuf,8);
563 nmb->header.arcount = RSVAL(inbuf,10);
565 if (nmb->header.qdcount) {
566 offset = parse_nmb_name(inbuf,12,length,
567 &nmb->question.question_name);
568 if (!offset)
569 return(False);
571 if (length - (12+offset) < 4)
572 return(False);
573 nmb->question.question_type = RSVAL(inbuf,12+offset);
574 nmb->question.question_class = RSVAL(inbuf,12+offset+2);
576 offset += 12+4;
577 } else {
578 offset = 12;
581 /* and any resource records */
582 if (nmb->header.ancount &&
583 !parse_alloc_res_rec(inbuf,&offset,length,&nmb->answers,
584 nmb->header.ancount))
585 return(False);
587 if (nmb->header.nscount &&
588 !parse_alloc_res_rec(inbuf,&offset,length,&nmb->nsrecs,
589 nmb->header.nscount))
590 return(False);
592 if (nmb->header.arcount &&
593 !parse_alloc_res_rec(inbuf,&offset,length,
594 &nmb->additional, nmb->header.arcount))
595 return(False);
597 return(True);
600 /*******************************************************************
601 'Copy constructor' for an nmb packet.
602 ******************************************************************/
604 static struct packet_struct *copy_nmb_packet(struct packet_struct *packet)
606 struct nmb_packet *nmb;
607 struct nmb_packet *copy_nmb;
608 struct packet_struct *pkt_copy;
610 if(( pkt_copy = SMB_MALLOC_P(struct packet_struct)) == NULL) {
611 DEBUG(0,("copy_nmb_packet: malloc fail.\n"));
612 return NULL;
615 /* Structure copy of entire thing. */
617 *pkt_copy = *packet;
619 /* Ensure this copy is not locked. */
620 pkt_copy->locked = False;
621 pkt_copy->recv_fd = -1;
622 pkt_copy->send_fd = -1;
624 /* Ensure this copy has no resource records. */
625 nmb = &packet->packet.nmb;
626 copy_nmb = &pkt_copy->packet.nmb;
628 copy_nmb->answers = NULL;
629 copy_nmb->nsrecs = NULL;
630 copy_nmb->additional = NULL;
632 /* Now copy any resource records. */
634 if (nmb->answers) {
635 if((copy_nmb->answers = SMB_MALLOC_ARRAY(
636 struct res_rec,nmb->header.ancount)) == NULL)
637 goto free_and_exit;
638 memcpy((char *)copy_nmb->answers, (char *)nmb->answers,
639 nmb->header.ancount * sizeof(struct res_rec));
641 if (nmb->nsrecs) {
642 if((copy_nmb->nsrecs = SMB_MALLOC_ARRAY(
643 struct res_rec, nmb->header.nscount)) == NULL)
644 goto free_and_exit;
645 memcpy((char *)copy_nmb->nsrecs, (char *)nmb->nsrecs,
646 nmb->header.nscount * sizeof(struct res_rec));
648 if (nmb->additional) {
649 if((copy_nmb->additional = SMB_MALLOC_ARRAY(
650 struct res_rec, nmb->header.arcount)) == NULL)
651 goto free_and_exit;
652 memcpy((char *)copy_nmb->additional, (char *)nmb->additional,
653 nmb->header.arcount * sizeof(struct res_rec));
656 return pkt_copy;
658 free_and_exit:
660 SAFE_FREE(copy_nmb->answers);
661 SAFE_FREE(copy_nmb->nsrecs);
662 SAFE_FREE(copy_nmb->additional);
663 SAFE_FREE(pkt_copy);
665 DEBUG(0,("copy_nmb_packet: malloc fail in resource records.\n"));
666 return NULL;
669 /*******************************************************************
670 'Copy constructor' for a dgram packet.
671 ******************************************************************/
673 static struct packet_struct *copy_dgram_packet(struct packet_struct *packet)
675 struct packet_struct *pkt_copy;
677 if(( pkt_copy = SMB_MALLOC_P(struct packet_struct)) == NULL) {
678 DEBUG(0,("copy_dgram_packet: malloc fail.\n"));
679 return NULL;
682 /* Structure copy of entire thing. */
684 *pkt_copy = *packet;
686 /* Ensure this copy is not locked. */
687 pkt_copy->locked = False;
688 pkt_copy->recv_fd = -1;
689 pkt_copy->send_fd = -1;
691 /* There are no additional pointers in a dgram packet,
692 we are finished. */
693 return pkt_copy;
696 /*******************************************************************
697 'Copy constructor' for a generic packet.
698 ******************************************************************/
700 struct packet_struct *copy_packet(struct packet_struct *packet)
702 if(packet->packet_type == NMB_PACKET)
703 return copy_nmb_packet(packet);
704 else if (packet->packet_type == DGRAM_PACKET)
705 return copy_dgram_packet(packet);
706 return NULL;
709 /*******************************************************************
710 Free up any resources associated with an nmb packet.
711 ******************************************************************/
713 static void free_nmb_packet(struct nmb_packet *nmb)
715 SAFE_FREE(nmb->answers);
716 SAFE_FREE(nmb->nsrecs);
717 SAFE_FREE(nmb->additional);
720 /*******************************************************************
721 Free up any resources associated with a dgram packet.
722 ******************************************************************/
724 static void free_dgram_packet(struct dgram_packet *nmb)
726 /* We have nothing to do for a dgram packet. */
729 /*******************************************************************
730 Free up any resources associated with a packet.
731 ******************************************************************/
733 void free_packet(struct packet_struct *packet)
735 if (packet->locked)
736 return;
737 if (packet->packet_type == NMB_PACKET)
738 free_nmb_packet(&packet->packet.nmb);
739 else if (packet->packet_type == DGRAM_PACKET)
740 free_dgram_packet(&packet->packet.dgram);
741 ZERO_STRUCTPN(packet);
742 SAFE_FREE(packet);
745 int packet_trn_id(struct packet_struct *p)
747 int result;
748 switch (p->packet_type) {
749 case NMB_PACKET:
750 result = p->packet.nmb.header.name_trn_id;
751 break;
752 case DGRAM_PACKET:
753 result = p->packet.dgram.header.dgm_id;
754 break;
755 default:
756 result = -1;
758 return result;
761 /*******************************************************************
762 Parse a packet buffer into a packet structure.
763 ******************************************************************/
765 struct packet_struct *parse_packet(char *buf,int length,
766 enum packet_type packet_type,
767 struct in_addr ip,
768 int port)
770 struct packet_struct *p;
771 bool ok=False;
773 p = SMB_MALLOC_P(struct packet_struct);
774 if (!p)
775 return(NULL);
777 ZERO_STRUCTP(p); /* initialize for possible padding */
779 p->next = NULL;
780 p->prev = NULL;
781 p->ip = ip;
782 p->port = port;
783 p->locked = False;
784 p->timestamp = time(NULL);
785 p->packet_type = packet_type;
787 switch (packet_type) {
788 case NMB_PACKET:
789 ok = parse_nmb(buf,length,&p->packet.nmb);
790 break;
792 case DGRAM_PACKET:
793 ok = parse_dgram(buf,length,&p->packet.dgram);
794 break;
797 if (!ok) {
798 free_packet(p);
799 return NULL;
802 return p;
805 /*******************************************************************
806 Read a packet from a socket and parse it, returning a packet ready
807 to be used or put on the queue. This assumes a UDP socket.
808 ******************************************************************/
810 struct packet_struct *read_packet(int fd,enum packet_type packet_type)
812 struct packet_struct *packet;
813 struct sockaddr_storage sa;
814 struct sockaddr_in *si = (struct sockaddr_in *)&sa;
815 char buf[MAX_DGRAM_SIZE];
816 int length;
818 length = read_udp_v4_socket(fd,buf,sizeof(buf),&sa);
819 if (length < MIN_DGRAM_SIZE || sa.ss_family != AF_INET) {
820 return NULL;
823 packet = parse_packet(buf,
824 length,
825 packet_type,
826 si->sin_addr,
827 ntohs(si->sin_port));
828 if (!packet)
829 return NULL;
831 packet->recv_fd = fd;
832 packet->send_fd = -1;
834 DEBUG(5,("Received a packet of len %d from (%s) port %d\n",
835 length, inet_ntoa(packet->ip), packet->port ) );
837 return(packet);
840 /*******************************************************************
841 Send a udp packet on a already open socket.
842 ******************************************************************/
844 static bool send_udp(int fd,char *buf,int len,struct in_addr ip,int port)
846 bool ret = False;
847 int i;
848 struct sockaddr_in sock_out;
850 /* set the address and port */
851 memset((char *)&sock_out,'\0',sizeof(sock_out));
852 putip((char *)&sock_out.sin_addr,(char *)&ip);
853 sock_out.sin_port = htons( port );
854 sock_out.sin_family = AF_INET;
856 DEBUG( 5, ( "Sending a packet of len %d to (%s) on port %d\n",
857 len, inet_ntoa(ip), port ) );
860 * Patch to fix asynch error notifications from Linux kernel.
863 for (i = 0; i < 5; i++) {
864 ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out,
865 sizeof(sock_out)) >= 0);
866 if (ret || errno != ECONNREFUSED)
867 break;
870 if (!ret)
871 DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n",
872 inet_ntoa(ip),port,strerror(errno)));
874 return(ret);
877 /*******************************************************************
878 Build a dgram packet ready for sending.
879 If buf == NULL this is a length calculation.
880 ******************************************************************/
882 static int build_dgram(char *buf, size_t len, struct dgram_packet *dgram)
884 unsigned char *ubuf = (unsigned char *)buf;
885 int offset=0;
887 /* put in the header */
888 if (buf) {
889 ubuf[0] = dgram->header.msg_type;
890 ubuf[1] = (((int)dgram->header.flags.node_type)<<2);
891 if (dgram->header.flags.more)
892 ubuf[1] |= 1;
893 if (dgram->header.flags.first)
894 ubuf[1] |= 2;
895 RSSVAL(ubuf,2,dgram->header.dgm_id);
896 putip(ubuf+4,(char *)&dgram->header.source_ip);
897 RSSVAL(ubuf,8,dgram->header.source_port);
898 RSSVAL(ubuf,12,dgram->header.packet_offset);
901 offset = 14;
903 if (dgram->header.msg_type == 0x10 ||
904 dgram->header.msg_type == 0x11 ||
905 dgram->header.msg_type == 0x12) {
906 offset += put_nmb_name((char *)ubuf,len,offset,&dgram->source_name);
907 offset += put_nmb_name((char *)ubuf,len,offset,&dgram->dest_name);
910 if (buf) {
911 memcpy(ubuf+offset,dgram->data,dgram->datasize);
913 offset += dgram->datasize;
915 /* automatically set the dgm_length
916 * NOTE: RFC1002 says the dgm_length does *not*
917 * include the fourteen-byte header. crh
919 dgram->header.dgm_length = (offset - 14);
920 if (buf) {
921 RSSVAL(ubuf,10,dgram->header.dgm_length);
924 return offset;
927 /*******************************************************************
928 Build a nmb name
929 *******************************************************************/
931 void make_nmb_name( struct nmb_name *n, const char *name, int type)
933 fstring unix_name;
934 memset( (char *)n, '\0', sizeof(struct nmb_name) );
935 fstrcpy(unix_name, name);
936 strupper_m(unix_name);
937 push_ascii(n->name, unix_name, sizeof(n->name), STR_TERMINATE);
938 n->name_type = (unsigned int)type & 0xFF;
939 push_ascii(n->scope, lp_netbios_scope(), 64, STR_TERMINATE);
942 /*******************************************************************
943 Compare two nmb names
944 ******************************************************************/
946 bool nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2)
948 return ((n1->name_type == n2->name_type) &&
949 strequal(n1->name ,n2->name ) &&
950 strequal(n1->scope,n2->scope));
953 /*******************************************************************
954 Build a nmb packet ready for sending.
955 If buf == NULL this is a length calculation.
956 ******************************************************************/
958 static int build_nmb(char *buf, size_t len, struct nmb_packet *nmb)
960 unsigned char *ubuf = (unsigned char *)buf;
961 int offset=0;
963 if (len && len < 12) {
964 return 0;
967 /* put in the header */
968 if (buf) {
969 RSSVAL(ubuf,offset,nmb->header.name_trn_id);
970 ubuf[offset+2] = (nmb->header.opcode & 0xF) << 3;
971 if (nmb->header.response)
972 ubuf[offset+2] |= (1<<7);
973 if (nmb->header.nm_flags.authoritative &&
974 nmb->header.response)
975 ubuf[offset+2] |= 0x4;
976 if (nmb->header.nm_flags.trunc)
977 ubuf[offset+2] |= 0x2;
978 if (nmb->header.nm_flags.recursion_desired)
979 ubuf[offset+2] |= 0x1;
980 if (nmb->header.nm_flags.recursion_available &&
981 nmb->header.response)
982 ubuf[offset+3] |= 0x80;
983 if (nmb->header.nm_flags.bcast)
984 ubuf[offset+3] |= 0x10;
985 ubuf[offset+3] |= (nmb->header.rcode & 0xF);
987 RSSVAL(ubuf,offset+4,nmb->header.qdcount);
988 RSSVAL(ubuf,offset+6,nmb->header.ancount);
989 RSSVAL(ubuf,offset+8,nmb->header.nscount);
990 RSSVAL(ubuf,offset+10,nmb->header.arcount);
993 offset += 12;
994 if (nmb->header.qdcount) {
995 /* XXXX this doesn't handle a qdcount of > 1 */
996 if (len) {
997 /* Length check. */
998 int extra = put_nmb_name(NULL,0,offset,
999 &nmb->question.question_name);
1000 if (offset + extra > len) {
1001 return 0;
1004 offset += put_nmb_name((char *)ubuf,len,offset,
1005 &nmb->question.question_name);
1006 if (buf) {
1007 RSSVAL(ubuf,offset,nmb->question.question_type);
1008 RSSVAL(ubuf,offset+2,nmb->question.question_class);
1010 offset += 4;
1013 if (nmb->header.ancount) {
1014 if (len) {
1015 /* Length check. */
1016 int extra = put_res_rec(NULL,0,offset,nmb->answers,
1017 nmb->header.ancount);
1018 if (offset + extra > len) {
1019 return 0;
1022 offset += put_res_rec((char *)ubuf,len,offset,nmb->answers,
1023 nmb->header.ancount);
1026 if (nmb->header.nscount) {
1027 if (len) {
1028 /* Length check. */
1029 int extra = put_res_rec(NULL,0,offset,nmb->nsrecs,
1030 nmb->header.nscount);
1031 if (offset + extra > len) {
1032 return 0;
1035 offset += put_res_rec((char *)ubuf,len,offset,nmb->nsrecs,
1036 nmb->header.nscount);
1040 * The spec says we must put compressed name pointers
1041 * in the following outgoing packets :
1042 * NAME_REGISTRATION_REQUEST, NAME_REFRESH_REQUEST,
1043 * NAME_RELEASE_REQUEST.
1046 if((nmb->header.response == False) &&
1047 ((nmb->header.opcode == NMB_NAME_REG_OPCODE) ||
1048 (nmb->header.opcode == NMB_NAME_RELEASE_OPCODE) ||
1049 (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_8) ||
1050 (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_9) ||
1051 (nmb->header.opcode == NMB_NAME_MULTIHOMED_REG_OPCODE)) &&
1052 (nmb->header.arcount == 1)) {
1054 if (len) {
1055 /* Length check. */
1056 int extra = put_compressed_name_ptr(NULL,offset,
1057 nmb->additional,12);
1058 if (offset + extra > len) {
1059 return 0;
1062 offset += put_compressed_name_ptr(ubuf,offset,
1063 nmb->additional,12);
1064 } else if (nmb->header.arcount) {
1065 if (len) {
1066 /* Length check. */
1067 int extra = put_res_rec(NULL,0,offset,nmb->additional,
1068 nmb->header.arcount);
1069 if (offset + extra > len) {
1070 return 0;
1073 offset += put_res_rec((char *)ubuf,len,offset,nmb->additional,
1074 nmb->header.arcount);
1076 return offset;
1079 /*******************************************************************
1080 Linearise a packet.
1081 ******************************************************************/
1083 int build_packet(char *buf, size_t buflen, struct packet_struct *p)
1085 int len = 0;
1087 switch (p->packet_type) {
1088 case NMB_PACKET:
1089 len = build_nmb(buf,buflen,&p->packet.nmb);
1090 break;
1092 case DGRAM_PACKET:
1093 len = build_dgram(buf,buflen,&p->packet.dgram);
1094 break;
1097 return len;
1100 /*******************************************************************
1101 Send a packet_struct.
1102 ******************************************************************/
1104 bool send_packet(struct packet_struct *p)
1106 char buf[1024];
1107 int len=0;
1109 memset(buf,'\0',sizeof(buf));
1111 len = build_packet(buf, sizeof(buf), p);
1113 if (!len)
1114 return(False);
1116 return(send_udp(p->send_fd,buf,len,p->ip,p->port));
1119 /****************************************************************************
1120 Receive a UDP/138 packet either via UDP or from the unexpected packet
1121 queue. The packet must be a reply packet and have the specified mailslot name
1122 The timeout is in milliseconds.
1123 ***************************************************************************/
1125 /****************************************************************************
1126 See if a datagram has the right mailslot name.
1127 ***************************************************************************/
1129 bool match_mailslot_name(struct packet_struct *p, const char *mailslot_name)
1131 struct dgram_packet *dgram = &p->packet.dgram;
1132 char *buf;
1134 buf = &dgram->data[0];
1135 buf -= 4;
1137 buf = smb_buf(buf);
1139 if (memcmp(buf, mailslot_name, strlen(mailslot_name)+1) == 0) {
1140 return True;
1143 return False;
1146 /****************************************************************************
1147 Return the number of bits that match between two len character buffers
1148 ***************************************************************************/
1150 int matching_len_bits(const unsigned char *p1, const unsigned char *p2, size_t len)
1152 size_t i, j;
1153 int ret = 0;
1154 for (i=0; i<len; i++) {
1155 if (p1[i] != p2[i])
1156 break;
1157 ret += 8;
1160 if (i==len)
1161 return ret;
1163 for (j=0; j<8; j++) {
1164 if ((p1[i] & (1<<(7-j))) != (p2[i] & (1<<(7-j))))
1165 break;
1166 ret++;
1169 return ret;
1172 static unsigned char sort_ip[4];
1174 /****************************************************************************
1175 Compare two query reply records.
1176 ***************************************************************************/
1178 static int name_query_comp(unsigned char *p1, unsigned char *p2)
1180 return matching_len_bits(p2+2, sort_ip, 4) -
1181 matching_len_bits(p1+2, sort_ip, 4);
1184 /****************************************************************************
1185 Sort a set of 6 byte name query response records so that the IPs that
1186 have the most leading bits in common with the specified address come first.
1187 ***************************************************************************/
1189 void sort_query_replies(char *data, int n, struct in_addr ip)
1191 if (n <= 1)
1192 return;
1194 putip(sort_ip, (char *)&ip);
1196 /* TODO:
1197 this can't use TYPESAFE_QSORT() as the types are wrong.
1198 It should be fixed to use a real type instead of char*
1200 qsort(data, n, 6, QSORT_CAST name_query_comp);
1203 /****************************************************************************
1204 Interpret the weird netbios "name" into a unix fstring. Return the name type.
1205 Returns -1 on error.
1206 ****************************************************************************/
1208 static int name_interpret(unsigned char *buf, size_t buf_len,
1209 unsigned char *in, fstring name)
1211 unsigned char *end_ptr = buf + buf_len;
1212 int ret;
1213 unsigned int len;
1214 fstring out_string;
1215 unsigned char *out = (unsigned char *)out_string;
1217 *out=0;
1219 if (in >= end_ptr) {
1220 return -1;
1222 len = (*in++) / 2;
1224 if (len<1) {
1225 return -1;
1228 while (len--) {
1229 if (&in[1] >= end_ptr) {
1230 return -1;
1232 if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
1233 *out = 0;
1234 return(0);
1236 *out = ((in[0]-'A')<<4) + (in[1]-'A');
1237 in += 2;
1238 out++;
1239 if (PTR_DIFF(out,out_string) >= sizeof(fstring)) {
1240 return -1;
1243 ret = out[-1];
1244 out[-1] = 0;
1246 pull_ascii_fstring(name, out_string);
1248 return(ret);
1251 /****************************************************************************
1252 Mangle a name into netbios format.
1253 Note: <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
1254 ****************************************************************************/
1256 char *name_mangle(TALLOC_CTX *mem_ctx, const char *In, char name_type)
1258 int i;
1259 int len;
1260 nstring buf;
1261 char *result;
1262 char *p;
1264 result = talloc_array(mem_ctx, char, 33 + strlen(lp_netbios_scope()) + 2);
1265 if (result == NULL) {
1266 return NULL;
1268 p = result;
1270 /* Safely copy the input string, In, into buf[]. */
1271 if (strcmp(In,"*") == 0)
1272 put_name(buf, "*", '\0', 0x00);
1273 else {
1274 /* We use an fstring here as mb dos names can expend x3 when
1275 going to utf8. */
1276 fstring buf_unix;
1277 nstring buf_dos;
1279 pull_ascii_fstring(buf_unix, In);
1280 strupper_m(buf_unix);
1282 push_ascii_nstring(buf_dos, buf_unix);
1283 put_name(buf, buf_dos, ' ', name_type);
1286 /* Place the length of the first field into the output buffer. */
1287 p[0] = 32;
1288 p++;
1290 /* Now convert the name to the rfc1001/1002 format. */
1291 for( i = 0; i < MAX_NETBIOSNAME_LEN; i++ ) {
1292 p[i*2] = ( (buf[i] >> 4) & 0x000F ) + 'A';
1293 p[(i*2)+1] = (buf[i] & 0x000F) + 'A';
1295 p += 32;
1296 p[0] = '\0';
1298 /* Add the scope string. */
1299 for( i = 0, len = 0; *(lp_netbios_scope()) != '\0'; i++, len++ ) {
1300 switch( (lp_netbios_scope())[i] ) {
1301 case '\0':
1302 p[0] = len;
1303 if( len > 0 )
1304 p[len+1] = 0;
1305 return result;
1306 case '.':
1307 p[0] = len;
1308 p += (len + 1);
1309 len = -1;
1310 break;
1311 default:
1312 p[len+1] = (lp_netbios_scope())[i];
1313 break;
1317 return result;
1320 /****************************************************************************
1321 Find a pointer to a netbios name.
1322 ****************************************************************************/
1324 static unsigned char *name_ptr(unsigned char *buf, size_t buf_len, unsigned int ofs)
1326 unsigned char c = 0;
1328 if (ofs > buf_len || buf_len < 1) {
1329 return NULL;
1332 c = *(unsigned char *)(buf+ofs);
1333 if ((c & 0xC0) == 0xC0) {
1334 uint16 l = 0;
1336 if (ofs > buf_len - 1) {
1337 return NULL;
1339 l = RSVAL(buf, ofs) & 0x3FFF;
1340 if (l > buf_len) {
1341 return NULL;
1343 DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
1344 return(buf + l);
1345 } else {
1346 return(buf+ofs);
1350 /****************************************************************************
1351 Extract a netbios name from a buf (into a unix string) return name type.
1352 Returns -1 on error.
1353 ****************************************************************************/
1355 int name_extract(unsigned char *buf, size_t buf_len, unsigned int ofs, fstring name)
1357 unsigned char *p = name_ptr(buf,buf_len,ofs);
1359 name[0] = '\0';
1360 if (p == NULL) {
1361 return -1;
1363 return(name_interpret(buf,buf_len,p,name));
1366 /****************************************************************************
1367 Return the total storage length of a mangled name.
1368 Returns -1 on error.
1369 ****************************************************************************/
1371 int name_len(unsigned char *s1, size_t buf_len)
1373 /* NOTE: this argument _must_ be unsigned */
1374 unsigned char *s = (unsigned char *)s1;
1375 int len = 0;
1377 if (buf_len < 1) {
1378 return -1;
1380 /* If the two high bits of the byte are set, return 2. */
1381 if (0xC0 == (*s & 0xC0)) {
1382 if (buf_len < 2) {
1383 return -1;
1385 return(2);
1388 /* Add up the length bytes. */
1389 for (len = 1; (*s); s += (*s) + 1) {
1390 len += *s + 1;
1391 if (len > buf_len) {
1392 return -1;
1396 return(len);