ctdb-server: Clean up connection tracking functions
[samba4-gss.git] / source3 / libsmb / nmblib.c
blob2297dd9ded948f9a2c6281fd939d8c4ff9f19e34
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"
24 #include "lib/util/string_wrappers.h"
26 const char *global_nmbd_socket_dir(void)
28 return lp_parm_const_string(-1, "nmbd", "socket dir",
29 get_dyn_NMBDSOCKETDIR());
32 static const struct opcode_names {
33 const char *nmb_opcode_name;
34 int opcode;
35 } nmb_header_opcode_names[] = {
36 {"Query", 0 },
37 {"Registration", 5 },
38 {"Release", 6 },
39 {"WACK", 7 },
40 {"Refresh", 8 },
41 {"Refresh(altcode)", 9 },
42 {"Multi-homed Registration", 15 },
43 {0, -1 }
46 /****************************************************************************
47 Lookup a nmb opcode name.
48 ****************************************************************************/
50 static const char *lookup_opcode_name( int opcode )
52 const struct opcode_names *op_namep;
53 int i;
55 for(i = 0; nmb_header_opcode_names[i].nmb_opcode_name != 0; i++) {
56 op_namep = &nmb_header_opcode_names[i];
57 if(opcode == op_namep->opcode)
58 return op_namep->nmb_opcode_name;
60 return "<unknown opcode>";
63 /****************************************************************************
64 Print out a res_rec structure.
65 ****************************************************************************/
67 static void debug_nmb_res_rec(struct res_rec *res, const char *hdr)
69 int i, j;
71 DEBUGADD( 4, ( " %s: nmb_name=%s rr_type=%d rr_class=%d ttl=%d\n",
72 hdr,
73 nmb_namestr(&res->rr_name),
74 res->rr_type,
75 res->rr_class,
76 res->ttl ) );
78 if (res->rdlength == 0) {
79 return;
82 for (i = 0; i < res->rdlength; i+= MAX_NETBIOSNAME_LEN) {
83 DEBUGADD(4, (" %s %3x char ", hdr, i));
85 for (j = 0; j < MAX_NETBIOSNAME_LEN; j++) {
86 unsigned char x = res->rdata[i+j];
87 if (x < 32 || x > 127)
88 x = '.';
90 if (i+j >= res->rdlength)
91 break;
92 DEBUGADD(4, ("%c", x));
95 DEBUGADD(4, (" hex "));
97 for (j = 0; j < MAX_NETBIOSNAME_LEN; j++) {
98 if (i+j >= res->rdlength)
99 break;
100 DEBUGADD(4, ("%02X", (unsigned char)res->rdata[i+j]));
103 DEBUGADD(4, ("\n"));
107 /****************************************************************************
108 Process a nmb packet.
109 ****************************************************************************/
111 void debug_nmb_packet(struct packet_struct *p)
113 struct nmb_packet *nmb = &p->packet.nmb;
115 if( DEBUGLVL( 4 ) ) {
116 dbgtext( "nmb packet from %s(%d) header: id=%d "
117 "opcode=%s(%d) response=%s\n",
118 inet_ntoa(p->ip), p->port,
119 nmb->header.name_trn_id,
120 lookup_opcode_name(nmb->header.opcode),
121 nmb->header.opcode,
122 BOOLSTR(nmb->header.response) );
123 dbgtext( " header: flags: bcast=%s rec_avail=%s "
124 "rec_des=%s trunc=%s auth=%s\n",
125 BOOLSTR(nmb->header.nm_flags.bcast),
126 BOOLSTR(nmb->header.nm_flags.recursion_available),
127 BOOLSTR(nmb->header.nm_flags.recursion_desired),
128 BOOLSTR(nmb->header.nm_flags.trunc),
129 BOOLSTR(nmb->header.nm_flags.authoritative) );
130 dbgtext( " header: rcode=%d qdcount=%d ancount=%d "
131 "nscount=%d arcount=%d\n",
132 nmb->header.rcode,
133 nmb->header.qdcount,
134 nmb->header.ancount,
135 nmb->header.nscount,
136 nmb->header.arcount );
139 if (nmb->header.qdcount) {
140 DEBUGADD( 4, ( " question: q_name=%s q_type=%d q_class=%d\n",
141 nmb_namestr(&nmb->question.question_name),
142 nmb->question.question_type,
143 nmb->question.question_class) );
146 if (nmb->answers && nmb->header.ancount) {
147 debug_nmb_res_rec(nmb->answers,"answers");
149 if (nmb->nsrecs && nmb->header.nscount) {
150 debug_nmb_res_rec(nmb->nsrecs,"nsrecs");
152 if (nmb->additional && nmb->header.arcount) {
153 debug_nmb_res_rec(nmb->additional,"additional");
157 /*******************************************************************
158 Handle "compressed" name pointers.
159 ******************************************************************/
161 static bool handle_name_ptrs(unsigned char *ubuf,int *offset,int length,
162 bool *got_pointer,int *ret)
164 int loop_count=0;
166 while ((ubuf[*offset] & 0xC0) == 0xC0) {
167 if (!*got_pointer)
168 (*ret) += 2;
169 (*got_pointer)=True;
170 if (*offset > length - 2) {
171 return False;
173 (*offset) = ((ubuf[*offset] & ~0xC0)<<8) | ubuf[(*offset)+1];
174 if (loop_count++ == 10 ||
175 (*offset) < 0 || (*offset)>(length-2)) {
176 return False;
179 return True;
182 /*******************************************************************
183 Parse a nmb name from "compressed" format to something readable
184 return the space taken by the name, or 0 if the name is invalid
185 ******************************************************************/
187 static int parse_nmb_name(char *inbuf,int ofs,int length, struct nmb_name *name)
189 size_t m,n=0;
190 unsigned char *ubuf = (unsigned char *)inbuf;
191 int ret = 0;
192 bool got_pointer=False;
193 size_t loop_count=0;
194 int offset = ofs;
196 if (length - offset < 2)
197 return(0);
199 /* handle initial name pointers */
200 if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret))
201 return(0);
203 m = ubuf[offset];
205 /* m must be 32 to exactly fill in the 16 bytes of the netbios name */
206 if (m != 32) {
207 return 0;
209 /* Cannot go past length. */
210 if (offset+m+2 > length) {
211 return 0;
214 memset((char *)name,'\0',sizeof(*name));
216 /* the "compressed" part */
217 if (!got_pointer)
218 ret += m + 2;
219 offset++;
220 while (m > 0) {
221 unsigned char c1,c2;
222 c1 = ubuf[offset++]-'A';
223 c2 = ubuf[offset++]-'A';
224 if ((c1 & 0xF0) || (c2 & 0xF0)) {
225 return(0);
227 if (n >= sizeof(name->name)) {
228 return 0;
230 name->name[n++] = (c1<<4) | c2;
231 m -= 2;
234 * RFC1002: For a valid NetBIOS name, exiting from the above,
235 * n *must* be MAX_NETBIOSNAME_LEN (16).
237 if (n != MAX_NETBIOSNAME_LEN) {
238 return 0;
241 /* parse out the name type, its always
242 * in the 16th byte of the name */
243 name->name_type = ((unsigned char)name->name[15]) & 0xff;
245 /* remove trailing spaces */
246 name->name[15] = 0;
247 n = 14;
248 while (n && name->name[n]==' ')
249 name->name[n--] = 0;
251 /* now the domain parts (if any) */
252 n = 0;
253 while (ubuf[offset]) {
254 /* we can have pointers within the domain part as well */
255 if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret))
256 return(0);
258 m = ubuf[offset];
260 * Don't allow null domain parts.
262 if (!m)
263 return(0);
264 if (!got_pointer)
265 ret += m+1;
266 if (n)
267 name->scope[n++] = '.';
268 if (m+2+offset>length || n+m+1>sizeof(name->scope))
269 return(0);
270 offset++;
271 while (m--)
272 name->scope[n++] = (char)ubuf[offset++];
275 * Watch for malicious loops.
277 if (loop_count++ == 10)
278 return 0;
280 name->scope[n++] = 0;
282 return(ret);
285 /****************************************************************************
286 Put a netbios name, padding(s) and a name type into a 16 character buffer.
287 name is already in DOS charset.
288 [15 bytes name + padding][1 byte name type].
289 ****************************************************************************/
291 void put_name(char *dest, const char *name, int pad, unsigned int name_type)
293 size_t len = strlen(name);
295 memcpy(dest, name, (len < MAX_NETBIOSNAME_LEN) ?
296 len : MAX_NETBIOSNAME_LEN - 1);
297 if (len < MAX_NETBIOSNAME_LEN - 1) {
298 memset(dest + len, pad, MAX_NETBIOSNAME_LEN - 1 - len);
300 dest[MAX_NETBIOSNAME_LEN - 1] = name_type;
303 /*******************************************************************
304 Put a compressed nmb name into a buffer. Return the length of the
305 compressed name.
307 Compressed names are really weird. The "compression" doubles the
308 size. The idea is that it also means that compressed names conform
309 to the domain name system. See RFC1002.
311 If buf == NULL this is a length calculation.
312 ******************************************************************/
314 static int put_nmb_name(char *buf, size_t buflen, int offset,struct nmb_name *name)
316 int ret,m;
317 nstring buf1;
318 char *p;
320 if (strcmp(name->name,"*") == 0) {
321 /* special case for wildcard name */
322 put_name(buf1, "*", '\0', name->name_type);
323 } else {
324 put_name(buf1, name->name, ' ', name->name_type);
327 if (buf) {
328 if (offset >= buflen) {
329 return 0;
331 buf[offset] = 0x20;
334 ret = 34;
336 for (m=0;m<MAX_NETBIOSNAME_LEN;m++) {
337 if (buf) {
338 if (offset+2+2*m >= buflen) {
339 return 0;
341 buf[offset+1+2*m] = 'A' + ((buf1[m]>>4)&0xF);
342 buf[offset+2+2*m] = 'A' + (buf1[m]&0xF);
345 offset += 33;
347 if (buf) {
348 if (offset >= buflen) {
349 return 0;
351 buf[offset] = 0;
354 if (name->scope[0]) {
355 /* XXXX this scope handling needs testing */
356 size_t scopenamelen = strlen(name->scope) + 1;
357 ret += scopenamelen;
358 if (buf) {
359 if (offset+1+scopenamelen >= buflen) {
360 return 0;
362 strlcpy(&buf[offset+1],name->scope,
363 buflen - (offset+1));
365 p = &buf[offset+1];
366 while ((p = strchr_m(p,'.'))) {
367 buf[offset] = PTR_DIFF(p,&buf[offset+1]);
368 offset += (buf[offset] + 1);
369 if (offset+1 >= buflen) {
370 return 0;
372 p = &buf[offset+1];
374 buf[offset] = strlen(&buf[offset+1]);
378 return ret;
381 /*******************************************************************
382 Useful for debugging messages.
383 ******************************************************************/
385 char *nmb_namestr(const struct nmb_name *n)
387 fstring name;
388 char *result;
390 pull_ascii_fstring(name, n->name);
391 if (!n->scope[0])
392 result = talloc_asprintf(talloc_tos(), "%s<%02x>", name,
393 n->name_type);
394 else
395 result = talloc_asprintf(talloc_tos(), "%s<%02x>.%s", name,
396 n->name_type, n->scope);
398 SMB_ASSERT(result != NULL);
399 return result;
402 /*******************************************************************
403 Allocate and parse some resource records.
404 ******************************************************************/
406 static bool parse_alloc_res_rec(char *inbuf,int *offset,int length,
407 struct res_rec **recs, int count)
409 int i;
411 *recs = SMB_MALLOC_ARRAY(struct res_rec, count);
412 if (!*recs)
413 return(False);
415 memset((char *)*recs,'\0',sizeof(**recs)*count);
417 for (i=0;i<count;i++) {
418 int l = parse_nmb_name(inbuf,*offset,length,
419 &(*recs)[i].rr_name);
420 (*offset) += l;
421 if (!l || (*offset)+10 > length) {
422 SAFE_FREE(*recs);
423 return(False);
425 (*recs)[i].rr_type = RSVAL(inbuf,(*offset));
426 (*recs)[i].rr_class = RSVAL(inbuf,(*offset)+2);
427 (*recs)[i].ttl = RIVAL(inbuf,(*offset)+4);
428 (*recs)[i].rdlength = RSVAL(inbuf,(*offset)+8);
429 (*offset) += 10;
430 if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) ||
431 (*offset)+(*recs)[i].rdlength > length) {
432 SAFE_FREE(*recs);
433 return(False);
435 memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength);
436 (*offset) += (*recs)[i].rdlength;
438 return(True);
441 /*******************************************************************
442 Put a resource record into a packet.
443 If buf == NULL this is a length calculation.
444 ******************************************************************/
446 static int put_res_rec(char *buf, size_t buflen, int offset,struct res_rec *recs,int count)
448 int ret=0;
449 int i;
451 for (i=0;i<count;i++) {
452 int l = put_nmb_name(buf,buflen,offset,&recs[i].rr_name);
453 offset += l;
454 ret += l;
455 if (buf) {
456 RSSVAL(buf,offset,recs[i].rr_type);
457 RSSVAL(buf,offset+2,recs[i].rr_class);
458 RSIVAL(buf,offset+4,(unsigned int)recs[i].ttl);
459 RSSVAL(buf,offset+8,recs[i].rdlength);
460 memcpy(buf+offset+10,recs[i].rdata,recs[i].rdlength);
462 offset += 10+recs[i].rdlength;
463 ret += 10+recs[i].rdlength;
466 return ret;
469 /*******************************************************************
470 Put a compressed name pointer record into a packet.
471 If buf == NULL this is a length calculation.
472 ******************************************************************/
474 static int put_compressed_name_ptr(unsigned char *buf,
475 int offset,
476 struct res_rec *rec,
477 int ptr_offset)
479 int ret=offset;
480 if (buf) {
481 buf[offset] = (0xC0 | ((ptr_offset >> 8) & 0xFF));
482 buf[offset+1] = (ptr_offset & 0xFF);
484 offset += 2;
485 if (buf) {
486 RSSVAL(buf,offset,rec->rr_type);
487 RSSVAL(buf,offset+2,rec->rr_class);
488 RSIVAL(buf,offset+4,rec->ttl);
489 RSSVAL(buf,offset+8,rec->rdlength);
490 memcpy(buf+offset+10,rec->rdata,rec->rdlength);
492 offset += 10+rec->rdlength;
493 ret = (offset - ret);
495 return ret;
498 /*******************************************************************
499 Parse a dgram packet. Return False if the packet can't be parsed
500 or is invalid for some reason, True otherwise.
502 This is documented in section 4.4.1 of RFC1002.
503 ******************************************************************/
505 static bool parse_dgram(char *inbuf,int length,struct dgram_packet *dgram)
507 size_t offset;
508 int flags;
510 memset((char *)dgram,'\0',sizeof(*dgram));
512 if (length < 14)
513 return(False);
515 dgram->header.msg_type = CVAL(inbuf,0);
516 flags = CVAL(inbuf,1);
517 dgram->header.flags.node_type = (enum node_type)((flags>>2)&3);
518 if (flags & 1)
519 dgram->header.flags.more = True;
520 if (flags & 2)
521 dgram->header.flags.first = True;
522 dgram->header.dgm_id = RSVAL(inbuf,2);
523 putip((char *)&dgram->header.source_ip,inbuf+4);
524 dgram->header.source_port = RSVAL(inbuf,8);
525 dgram->header.dgm_length = RSVAL(inbuf,10);
526 dgram->header.packet_offset = RSVAL(inbuf,12);
528 offset = 14;
530 if (dgram->header.msg_type == 0x10 ||
531 dgram->header.msg_type == 0x11 ||
532 dgram->header.msg_type == 0x12) {
533 offset += parse_nmb_name(inbuf,offset,length,
534 &dgram->source_name);
535 offset += parse_nmb_name(inbuf,offset,length,
536 &dgram->dest_name);
539 if (offset >= length || (length-offset > sizeof(dgram->data)))
540 return(False);
542 dgram->datasize = length-offset;
543 memcpy(dgram->data,inbuf+offset,dgram->datasize);
545 /* Paranioa. Ensure the last 2 bytes in the dgram buffer are
546 zero. This should be true anyway, just enforce it for
547 paranioa sake. JRA. */
548 SMB_ASSERT(dgram->datasize <= (sizeof(dgram->data)-2));
549 memset(&dgram->data[sizeof(dgram->data)-2], '\0', 2);
551 return(True);
554 /*******************************************************************
555 Parse a nmb packet. Return False if the packet can't be parsed
556 or is invalid for some reason, True otherwise.
557 ******************************************************************/
559 static bool parse_nmb(char *inbuf,int length,struct nmb_packet *nmb)
561 int nm_flags,offset;
563 memset((char *)nmb,'\0',sizeof(*nmb));
565 if (length < 12)
566 return(False);
568 /* parse the header */
569 nmb->header.name_trn_id = RSVAL(inbuf,0);
571 DEBUG(10,("parse_nmb: packet id = %d\n", nmb->header.name_trn_id));
573 nmb->header.opcode = (CVAL(inbuf,2) >> 3) & 0xF;
574 nmb->header.response = ((CVAL(inbuf,2)>>7)&1)?True:False;
575 nm_flags = ((CVAL(inbuf,2) & 0x7) << 4) + (CVAL(inbuf,3)>>4);
576 nmb->header.nm_flags.bcast = (nm_flags&1)?True:False;
577 nmb->header.nm_flags.recursion_available = (nm_flags&8)?True:False;
578 nmb->header.nm_flags.recursion_desired = (nm_flags&0x10)?True:False;
579 nmb->header.nm_flags.trunc = (nm_flags&0x20)?True:False;
580 nmb->header.nm_flags.authoritative = (nm_flags&0x40)?True:False;
581 nmb->header.rcode = CVAL(inbuf,3) & 0xF;
582 nmb->header.qdcount = RSVAL(inbuf,4);
583 nmb->header.ancount = RSVAL(inbuf,6);
584 nmb->header.nscount = RSVAL(inbuf,8);
585 nmb->header.arcount = RSVAL(inbuf,10);
587 if (nmb->header.qdcount) {
588 offset = parse_nmb_name(inbuf,12,length,
589 &nmb->question.question_name);
590 if (!offset)
591 return(False);
593 if (length - (12+offset) < 4)
594 return(False);
595 nmb->question.question_type = RSVAL(inbuf,12+offset);
596 nmb->question.question_class = RSVAL(inbuf,12+offset+2);
598 offset += 12+4;
599 } else {
600 offset = 12;
603 /* and any resource records */
604 if (nmb->header.ancount &&
605 !parse_alloc_res_rec(inbuf,&offset,length,&nmb->answers,
606 nmb->header.ancount))
607 return(False);
609 if (nmb->header.nscount &&
610 !parse_alloc_res_rec(inbuf,&offset,length,&nmb->nsrecs,
611 nmb->header.nscount))
612 return(False);
614 if (nmb->header.arcount &&
615 !parse_alloc_res_rec(inbuf,&offset,length,
616 &nmb->additional, nmb->header.arcount))
617 return(False);
619 return(True);
622 /*******************************************************************
623 'Copy constructor' for an nmb packet.
624 ******************************************************************/
626 static struct packet_struct *copy_nmb_packet(struct packet_struct *packet)
628 struct nmb_packet *nmb;
629 struct nmb_packet *copy_nmb;
630 struct packet_struct *pkt_copy;
632 if(( pkt_copy = SMB_MALLOC_P(struct packet_struct)) == NULL) {
633 DEBUG(0,("copy_nmb_packet: malloc fail.\n"));
634 return NULL;
637 /* Structure copy of entire thing. */
639 *pkt_copy = *packet;
641 /* Ensure this copy is not locked. */
642 pkt_copy->locked = False;
643 pkt_copy->recv_fd = -1;
644 pkt_copy->send_fd = -1;
646 /* Ensure this copy has no resource records. */
647 nmb = &packet->packet.nmb;
648 copy_nmb = &pkt_copy->packet.nmb;
650 copy_nmb->answers = NULL;
651 copy_nmb->nsrecs = NULL;
652 copy_nmb->additional = NULL;
654 /* Now copy any resource records. */
656 if (nmb->answers) {
657 if((copy_nmb->answers = SMB_MALLOC_ARRAY(
658 struct res_rec,nmb->header.ancount)) == NULL)
659 goto free_and_exit;
660 memcpy((char *)copy_nmb->answers, (char *)nmb->answers,
661 nmb->header.ancount * sizeof(struct res_rec));
663 if (nmb->nsrecs) {
664 if((copy_nmb->nsrecs = SMB_MALLOC_ARRAY(
665 struct res_rec, nmb->header.nscount)) == NULL)
666 goto free_and_exit;
667 memcpy((char *)copy_nmb->nsrecs, (char *)nmb->nsrecs,
668 nmb->header.nscount * sizeof(struct res_rec));
670 if (nmb->additional) {
671 if((copy_nmb->additional = SMB_MALLOC_ARRAY(
672 struct res_rec, nmb->header.arcount)) == NULL)
673 goto free_and_exit;
674 memcpy((char *)copy_nmb->additional, (char *)nmb->additional,
675 nmb->header.arcount * sizeof(struct res_rec));
678 return pkt_copy;
680 free_and_exit:
682 SAFE_FREE(copy_nmb->answers);
683 SAFE_FREE(copy_nmb->nsrecs);
684 SAFE_FREE(copy_nmb->additional);
685 SAFE_FREE(pkt_copy);
687 DEBUG(0,("copy_nmb_packet: malloc fail in resource records.\n"));
688 return NULL;
691 /*******************************************************************
692 'Copy constructor' for a dgram packet.
693 ******************************************************************/
695 static struct packet_struct *copy_dgram_packet(struct packet_struct *packet)
697 struct packet_struct *pkt_copy;
699 if(( pkt_copy = SMB_MALLOC_P(struct packet_struct)) == NULL) {
700 DEBUG(0,("copy_dgram_packet: malloc fail.\n"));
701 return NULL;
704 /* Structure copy of entire thing. */
706 *pkt_copy = *packet;
708 /* Ensure this copy is not locked. */
709 pkt_copy->locked = False;
710 pkt_copy->recv_fd = -1;
711 pkt_copy->send_fd = -1;
713 /* There are no additional pointers in a dgram packet,
714 we are finished. */
715 return pkt_copy;
718 /*******************************************************************
719 'Copy constructor' for a generic packet.
720 ******************************************************************/
722 struct packet_struct *copy_packet(struct packet_struct *packet)
724 if(packet->packet_type == NMB_PACKET)
725 return copy_nmb_packet(packet);
726 else if (packet->packet_type == DGRAM_PACKET)
727 return copy_dgram_packet(packet);
728 return NULL;
731 /*******************************************************************
732 Free up any resources associated with an nmb packet.
733 ******************************************************************/
735 static void free_nmb_packet(struct nmb_packet *nmb)
737 SAFE_FREE(nmb->answers);
738 SAFE_FREE(nmb->nsrecs);
739 SAFE_FREE(nmb->additional);
742 /*******************************************************************
743 Free up any resources associated with a dgram packet.
744 ******************************************************************/
746 static void free_dgram_packet(struct dgram_packet *nmb)
748 /* We have nothing to do for a dgram packet. */
751 /*******************************************************************
752 Free up any resources associated with a packet.
753 ******************************************************************/
755 void free_packet(struct packet_struct *packet)
757 if (packet->locked)
758 return;
759 if (packet->packet_type == NMB_PACKET)
760 free_nmb_packet(&packet->packet.nmb);
761 else if (packet->packet_type == DGRAM_PACKET)
762 free_dgram_packet(&packet->packet.dgram);
763 ZERO_STRUCTPN(packet);
764 SAFE_FREE(packet);
767 int packet_trn_id(struct packet_struct *p)
769 int result;
770 switch (p->packet_type) {
771 case NMB_PACKET:
772 result = p->packet.nmb.header.name_trn_id;
773 break;
774 case DGRAM_PACKET:
775 result = p->packet.dgram.header.dgm_id;
776 break;
777 default:
778 result = -1;
780 return result;
783 /*******************************************************************
784 Parse a packet buffer into a packet structure.
785 ******************************************************************/
787 struct packet_struct *parse_packet(char *buf,int length,
788 enum packet_type packet_type,
789 struct in_addr ip,
790 int port)
792 struct packet_struct *p;
793 bool ok=False;
795 p = SMB_MALLOC_P(struct packet_struct);
796 if (!p)
797 return(NULL);
799 ZERO_STRUCTP(p); /* initialize for possible padding */
801 p->next = NULL;
802 p->prev = NULL;
803 p->ip = ip;
804 p->port = port;
805 p->locked = False;
806 p->timestamp = time(NULL);
807 p->packet_type = packet_type;
809 switch (packet_type) {
810 case NMB_PACKET:
811 ok = parse_nmb(buf,length,&p->packet.nmb);
812 break;
814 case DGRAM_PACKET:
815 ok = parse_dgram(buf,length,&p->packet.dgram);
816 break;
819 if (!ok) {
820 free_packet(p);
821 return NULL;
824 return p;
827 static struct packet_struct *copy_packet_talloc(
828 TALLOC_CTX *mem_ctx, const struct packet_struct *src)
830 struct packet_struct *pkt;
832 pkt = talloc_memdup(mem_ctx, src, sizeof(struct packet_struct));
833 if (pkt == NULL) {
834 return NULL;
836 pkt->locked = false;
837 pkt->recv_fd = -1;
838 pkt->send_fd = -1;
840 if (src->packet_type == NMB_PACKET) {
841 const struct nmb_packet *nsrc = &src->packet.nmb;
842 struct nmb_packet *ndst = &pkt->packet.nmb;
844 if (nsrc->answers != NULL) {
845 ndst->answers = talloc_memdup(
846 pkt, nsrc->answers,
847 sizeof(struct res_rec) * nsrc->header.ancount);
848 if (ndst->answers == NULL) {
849 goto fail;
852 if (nsrc->nsrecs != NULL) {
853 ndst->nsrecs = talloc_memdup(
854 pkt, nsrc->nsrecs,
855 sizeof(struct res_rec) * nsrc->header.nscount);
856 if (ndst->nsrecs == NULL) {
857 goto fail;
860 if (nsrc->additional != NULL) {
861 ndst->additional = talloc_memdup(
862 pkt, nsrc->additional,
863 sizeof(struct res_rec) * nsrc->header.arcount);
864 if (ndst->additional == NULL) {
865 goto fail;
870 return pkt;
873 * DGRAM packets have no substructures
876 fail:
877 TALLOC_FREE(pkt);
878 return NULL;
881 struct packet_struct *parse_packet_talloc(TALLOC_CTX *mem_ctx,
882 char *buf,int length,
883 enum packet_type packet_type,
884 struct in_addr ip,
885 int port)
887 struct packet_struct *pkt, *result;
889 pkt = parse_packet(buf, length, packet_type, ip, port);
890 if (pkt == NULL) {
891 return NULL;
893 result = copy_packet_talloc(mem_ctx, pkt);
894 free_packet(pkt);
895 return result;
898 /*******************************************************************
899 Send a udp packet on a already open socket.
900 ******************************************************************/
902 static bool send_udp(int fd,char *buf,int len,struct in_addr ip,int port)
904 bool ret = False;
905 int i;
906 struct sockaddr_in sock_out;
908 /* set the address and port */
909 memset((char *)&sock_out,'\0',sizeof(sock_out));
910 putip((char *)&sock_out.sin_addr,(char *)&ip);
911 sock_out.sin_port = htons( port );
912 sock_out.sin_family = AF_INET;
914 DEBUG( 5, ( "Sending a packet of len %d to (%s) on port %d\n",
915 len, inet_ntoa(ip), port ) );
918 * Patch to fix asynch error notifications from Linux kernel.
921 for (i = 0; i < 5; i++) {
922 ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out,
923 sizeof(sock_out)) >= 0);
924 if (ret || errno != ECONNREFUSED)
925 break;
928 if (!ret)
929 DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n",
930 inet_ntoa(ip),port,strerror(errno)));
932 return(ret);
935 /*******************************************************************
936 Build a dgram packet ready for sending.
937 If buf == NULL this is a length calculation.
938 ******************************************************************/
940 static int build_dgram(char *buf, size_t len, struct dgram_packet *dgram)
942 unsigned char *ubuf = (unsigned char *)buf;
943 int offset=0;
945 /* put in the header */
946 if (buf) {
947 ubuf[0] = dgram->header.msg_type;
948 ubuf[1] = (((int)dgram->header.flags.node_type)<<2);
949 if (dgram->header.flags.more)
950 ubuf[1] |= 1;
951 if (dgram->header.flags.first)
952 ubuf[1] |= 2;
953 RSSVAL(ubuf,2,dgram->header.dgm_id);
954 putip(ubuf+4,(char *)&dgram->header.source_ip);
955 RSSVAL(ubuf,8,dgram->header.source_port);
956 RSSVAL(ubuf,12,dgram->header.packet_offset);
959 offset = 14;
961 if (dgram->header.msg_type == 0x10 ||
962 dgram->header.msg_type == 0x11 ||
963 dgram->header.msg_type == 0x12) {
964 offset += put_nmb_name((char *)ubuf,len,offset,&dgram->source_name);
965 offset += put_nmb_name((char *)ubuf,len,offset,&dgram->dest_name);
968 if (buf) {
969 memcpy(ubuf+offset,dgram->data,dgram->datasize);
971 offset += dgram->datasize;
973 /* automatically set the dgm_length
974 * NOTE: RFC1002 says the dgm_length does *not*
975 * include the fourteen-byte header. crh
977 dgram->header.dgm_length = (offset - 14);
978 if (buf) {
979 RSSVAL(ubuf,10,dgram->header.dgm_length);
982 return offset;
985 /*******************************************************************
986 Build a nmb name
987 *******************************************************************/
989 void make_nmb_name( struct nmb_name *n, const char *name, int type)
991 fstring unix_name;
992 memset( (char *)n, '\0', sizeof(struct nmb_name) );
993 fstrcpy(unix_name, name);
994 (void)strupper_m(unix_name);
995 push_ascii(n->name, unix_name, sizeof(n->name), STR_TERMINATE);
996 n->name_type = (unsigned int)type & 0xFF;
997 push_ascii(n->scope, lp_netbios_scope(), 64, STR_TERMINATE);
1000 /*******************************************************************
1001 Compare two nmb names
1002 ******************************************************************/
1004 bool nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2)
1006 return ((n1->name_type == n2->name_type) &&
1007 strequal(n1->name ,n2->name ) &&
1008 strequal(n1->scope,n2->scope));
1011 /*******************************************************************
1012 Build a nmb packet ready for sending.
1013 If buf == NULL this is a length calculation.
1014 ******************************************************************/
1016 static int build_nmb(char *buf, size_t len, struct nmb_packet *nmb)
1018 unsigned char *ubuf = (unsigned char *)buf;
1019 int offset=0;
1021 if (len && len < 12) {
1022 return 0;
1025 /* put in the header */
1026 if (buf) {
1027 RSSVAL(ubuf,offset,nmb->header.name_trn_id);
1028 ubuf[offset+2] = (nmb->header.opcode & 0xF) << 3;
1029 if (nmb->header.response)
1030 ubuf[offset+2] |= (1<<7);
1031 if (nmb->header.nm_flags.authoritative &&
1032 nmb->header.response)
1033 ubuf[offset+2] |= 0x4;
1034 if (nmb->header.nm_flags.trunc)
1035 ubuf[offset+2] |= 0x2;
1036 if (nmb->header.nm_flags.recursion_desired)
1037 ubuf[offset+2] |= 0x1;
1038 if (nmb->header.nm_flags.recursion_available &&
1039 nmb->header.response)
1040 ubuf[offset+3] |= 0x80;
1041 if (nmb->header.nm_flags.bcast)
1042 ubuf[offset+3] |= 0x10;
1043 ubuf[offset+3] |= (nmb->header.rcode & 0xF);
1045 RSSVAL(ubuf,offset+4,nmb->header.qdcount);
1046 RSSVAL(ubuf,offset+6,nmb->header.ancount);
1047 RSSVAL(ubuf,offset+8,nmb->header.nscount);
1048 RSSVAL(ubuf,offset+10,nmb->header.arcount);
1051 offset += 12;
1052 if (nmb->header.qdcount) {
1053 /* XXXX this doesn't handle a qdcount of > 1 */
1054 if (len) {
1055 /* Length check. */
1056 int extra = put_nmb_name(NULL,0,offset,
1057 &nmb->question.question_name);
1058 if (offset + extra > len) {
1059 return 0;
1062 offset += put_nmb_name((char *)ubuf,len,offset,
1063 &nmb->question.question_name);
1064 if (buf) {
1065 RSSVAL(ubuf,offset,nmb->question.question_type);
1066 RSSVAL(ubuf,offset+2,nmb->question.question_class);
1068 offset += 4;
1071 if (nmb->header.ancount) {
1072 if (len) {
1073 /* Length check. */
1074 int extra = put_res_rec(NULL,0,offset,nmb->answers,
1075 nmb->header.ancount);
1076 if (offset + extra > len) {
1077 return 0;
1080 offset += put_res_rec((char *)ubuf,len,offset,nmb->answers,
1081 nmb->header.ancount);
1084 if (nmb->header.nscount) {
1085 if (len) {
1086 /* Length check. */
1087 int extra = put_res_rec(NULL,0,offset,nmb->nsrecs,
1088 nmb->header.nscount);
1089 if (offset + extra > len) {
1090 return 0;
1093 offset += put_res_rec((char *)ubuf,len,offset,nmb->nsrecs,
1094 nmb->header.nscount);
1098 * The spec says we must put compressed name pointers
1099 * in the following outgoing packets :
1100 * NAME_REGISTRATION_REQUEST, NAME_REFRESH_REQUEST,
1101 * NAME_RELEASE_REQUEST.
1104 if((nmb->header.response == False) &&
1105 ((nmb->header.opcode == NMB_NAME_REG_OPCODE) ||
1106 (nmb->header.opcode == NMB_NAME_RELEASE_OPCODE) ||
1107 (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_8) ||
1108 (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_9) ||
1109 (nmb->header.opcode == NMB_NAME_MULTIHOMED_REG_OPCODE)) &&
1110 (nmb->header.arcount == 1)) {
1112 if (len) {
1113 /* Length check. */
1114 int extra = put_compressed_name_ptr(NULL,offset,
1115 nmb->additional,12);
1116 if (offset + extra > len) {
1117 return 0;
1120 offset += put_compressed_name_ptr(ubuf,offset,
1121 nmb->additional,12);
1122 } else if (nmb->header.arcount) {
1123 if (len) {
1124 /* Length check. */
1125 int extra = put_res_rec(NULL,0,offset,nmb->additional,
1126 nmb->header.arcount);
1127 if (offset + extra > len) {
1128 return 0;
1131 offset += put_res_rec((char *)ubuf,len,offset,nmb->additional,
1132 nmb->header.arcount);
1134 return offset;
1137 /*******************************************************************
1138 Linearise a packet.
1139 ******************************************************************/
1141 int build_packet(char *buf, size_t buflen, struct packet_struct *p)
1143 int len = 0;
1145 switch (p->packet_type) {
1146 case NMB_PACKET:
1147 len = build_nmb(buf,buflen,&p->packet.nmb);
1148 break;
1150 case DGRAM_PACKET:
1151 len = build_dgram(buf,buflen,&p->packet.dgram);
1152 break;
1155 return len;
1158 /*******************************************************************
1159 Send a packet_struct.
1160 ******************************************************************/
1162 bool send_packet(struct packet_struct *p)
1164 char buf[1024];
1165 int len=0;
1167 memset(buf,'\0',sizeof(buf));
1169 len = build_packet(buf, sizeof(buf), p);
1171 if (!len)
1172 return(False);
1174 return(send_udp(p->send_fd,buf,len,p->ip,p->port));
1177 /****************************************************************************
1178 Receive a UDP/138 packet either via UDP or from the unexpected packet
1179 queue. The packet must be a reply packet and have the specified mailslot name
1180 The timeout is in milliseconds.
1181 ***************************************************************************/
1183 /****************************************************************************
1184 See if a datagram has the right mailslot name.
1185 ***************************************************************************/
1187 bool match_mailslot_name(struct packet_struct *p, const char *mailslot_name)
1189 struct dgram_packet *dgram = &p->packet.dgram;
1190 char *buf;
1192 buf = &dgram->data[0];
1193 buf -= 4;
1195 buf = smb_buf(buf);
1197 if (memcmp(buf, mailslot_name, strlen(mailslot_name)+1) == 0) {
1198 return True;
1201 return False;
1204 /****************************************************************************
1205 Return the number of bits that match between two len character buffers
1206 ***************************************************************************/
1208 int matching_len_bits(const unsigned char *p1, const unsigned char *p2, size_t len)
1210 size_t i, j;
1211 int ret = 0;
1212 for (i=0; i<len; i++) {
1213 if (p1[i] != p2[i])
1214 break;
1215 ret += 8;
1218 if (i==len)
1219 return ret;
1221 for (j=0; j<8; j++) {
1222 if ((p1[i] & (1<<(7-j))) != (p2[i] & (1<<(7-j))))
1223 break;
1224 ret++;
1227 return ret;
1230 static unsigned char sort_ip[4];
1232 /****************************************************************************
1233 Compare two query reply records.
1234 ***************************************************************************/
1236 static int name_query_comp(unsigned char *p1, unsigned char *p2)
1238 int a = matching_len_bits(p1+2, sort_ip, 4);
1239 int b = matching_len_bits(p2+2, sort_ip, 4);
1240 /* reverse sort -- p2 derived value comes first */
1241 return NUMERIC_CMP(b, a);
1244 /****************************************************************************
1245 Sort a set of 6 byte name query response records so that the IPs that
1246 have the most leading bits in common with the specified address come first.
1247 ***************************************************************************/
1249 void sort_query_replies(char *data, int n, struct in_addr ip)
1251 if (n <= 1)
1252 return;
1254 putip(sort_ip, (char *)&ip);
1256 /* TODO:
1257 this can't use TYPESAFE_QSORT() as the types are wrong.
1258 It should be fixed to use a real type instead of char*
1260 qsort(data, n, 6, QSORT_CAST name_query_comp);
1263 /****************************************************************************
1264 Interpret the weird netbios "name" into a unix fstring. Return the name type.
1265 Returns -1 on error.
1266 ****************************************************************************/
1268 static int name_interpret(unsigned char *buf, size_t buf_len,
1269 unsigned char *in, fstring name)
1271 unsigned char *end_ptr = buf + buf_len;
1272 int ret;
1273 unsigned int len;
1274 fstring out_string;
1275 unsigned char *out = (unsigned char *)out_string;
1277 *out=0;
1279 if (in >= end_ptr) {
1280 return -1;
1282 len = (*in++) / 2;
1284 if (len<1) {
1285 return -1;
1288 while (len--) {
1289 if (&in[1] >= end_ptr) {
1290 return -1;
1292 if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
1293 *out = 0;
1294 return(0);
1296 *out = ((in[0]-'A')<<4) + (in[1]-'A');
1297 in += 2;
1298 out++;
1299 if (PTR_DIFF(out,out_string) >= sizeof(fstring)) {
1300 return -1;
1303 ret = out[-1];
1304 out[-1] = 0;
1306 pull_ascii_fstring(name, out_string);
1308 return(ret);
1311 /****************************************************************************
1312 Mangle a name into netbios format.
1313 Note: <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
1314 ****************************************************************************/
1316 char *name_mangle(TALLOC_CTX *mem_ctx, const char *In, char name_type)
1318 int i;
1319 int len;
1320 nstring buf;
1321 char *result;
1322 char *p;
1324 result = talloc_array(mem_ctx, char, 33 + strlen(lp_netbios_scope()) + 2);
1325 if (result == NULL) {
1326 return NULL;
1328 p = result;
1330 /* Safely copy the input string, In, into buf[]. */
1331 if (strcmp(In,"*") == 0)
1332 put_name(buf, "*", '\0', 0x00);
1333 else {
1334 /* We use an fstring here as mb dos names can expend x3 when
1335 going to utf8. */
1336 fstring buf_unix;
1337 nstring buf_dos;
1339 pull_ascii_fstring(buf_unix, In);
1340 if (!strupper_m(buf_unix)) {
1341 return NULL;
1344 push_ascii_nstring(buf_dos, buf_unix);
1345 put_name(buf, buf_dos, ' ', name_type);
1348 /* Place the length of the first field into the output buffer. */
1349 p[0] = 32;
1350 p++;
1352 /* Now convert the name to the rfc1001/1002 format. */
1353 for( i = 0; i < MAX_NETBIOSNAME_LEN; i++ ) {
1354 p[i*2] = ( (buf[i] >> 4) & 0x000F ) + 'A';
1355 p[(i*2)+1] = (buf[i] & 0x000F) + 'A';
1357 p += 32;
1358 p[0] = '\0';
1360 /* Add the scope string. */
1361 for( i = 0, len = 0; *(lp_netbios_scope()) != '\0'; i++, len++ ) {
1362 switch( (lp_netbios_scope())[i] ) {
1363 case '\0':
1364 p[0] = len;
1365 if( len > 0 )
1366 p[len+1] = 0;
1367 return result;
1368 case '.':
1369 p[0] = len;
1370 p += (len + 1);
1371 len = -1;
1372 break;
1373 default:
1374 p[len+1] = (lp_netbios_scope())[i];
1375 break;
1379 return result;
1382 /****************************************************************************
1383 Find a pointer to a netbios name.
1384 ****************************************************************************/
1386 static unsigned char *name_ptr(unsigned char *buf, size_t buf_len, unsigned int ofs)
1388 unsigned char c = 0;
1390 if (ofs > buf_len || buf_len < 1) {
1391 return NULL;
1394 c = *(unsigned char *)(buf+ofs);
1395 if ((c & 0xC0) == 0xC0) {
1396 uint16_t l = 0;
1398 if (ofs > buf_len - 1) {
1399 return NULL;
1401 l = RSVAL(buf, ofs) & 0x3FFF;
1402 if (l > buf_len) {
1403 return NULL;
1405 DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
1406 return(buf + l);
1407 } else {
1408 return(buf+ofs);
1412 /****************************************************************************
1413 Extract a netbios name from a buf (into a unix string) return name type.
1414 Returns -1 on error.
1415 ****************************************************************************/
1417 int name_extract(unsigned char *buf, size_t buf_len, unsigned int ofs, fstring name)
1419 unsigned char *p = name_ptr(buf,buf_len,ofs);
1421 name[0] = '\0';
1422 if (p == NULL) {
1423 return -1;
1425 return(name_interpret(buf,buf_len,p,name));
1428 /****************************************************************************
1429 Return the total storage length of a mangled name.
1430 Returns -1 on error.
1431 ****************************************************************************/
1433 int name_len(unsigned char *s1, size_t buf_len)
1435 /* NOTE: this argument _must_ be unsigned */
1436 unsigned char *s = (unsigned char *)s1;
1437 int len = 0;
1439 if (buf_len < 1) {
1440 return -1;
1442 /* If the two high bits of the byte are set, return 2. */
1443 if (0xC0 == (*s & 0xC0)) {
1444 if (buf_len < 2) {
1445 return -1;
1447 return(2);
1450 /* Add up the length bytes. */
1451 for (len = 1; (*s); s += (*s) + 1) {
1452 len += *s + 1;
1453 if (len > buf_len) {
1454 return -1;
1458 return(len);
1461 /*******************************************************************
1462 Setup the word count and byte count for a client smb message.
1463 ********************************************************************/
1465 int cli_set_message(char *buf,int num_words,int num_bytes,bool zero)
1467 if (zero && (num_words || num_bytes)) {
1468 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
1470 SCVAL(buf,smb_wct,num_words);
1471 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
1472 smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
1473 return (smb_size + num_words*2 + num_bytes);