smbd: set fsp_flags.is_fsa to true on printer file handles
[Samba.git] / source3 / libsmb / nmblib.c
blobc90e92ebb697bfdfcce82ddfc5d163749808f017
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 static const struct opcode_names {
27 const char *nmb_opcode_name;
28 int opcode;
29 } nmb_header_opcode_names[] = {
30 {"Query", 0 },
31 {"Registration", 5 },
32 {"Release", 6 },
33 {"WACK", 7 },
34 {"Refresh", 8 },
35 {"Refresh(altcode)", 9 },
36 {"Multi-homed Registration", 15 },
37 {0, -1 }
40 /****************************************************************************
41 Lookup a nmb opcode name.
42 ****************************************************************************/
44 static const char *lookup_opcode_name( int opcode )
46 const struct opcode_names *op_namep;
47 int i;
49 for(i = 0; nmb_header_opcode_names[i].nmb_opcode_name != 0; i++) {
50 op_namep = &nmb_header_opcode_names[i];
51 if(opcode == op_namep->opcode)
52 return op_namep->nmb_opcode_name;
54 return "<unknown opcode>";
57 /****************************************************************************
58 Print out a res_rec structure.
59 ****************************************************************************/
61 static void debug_nmb_res_rec(struct res_rec *res, const char *hdr)
63 int i, j;
65 DEBUGADD( 4, ( " %s: nmb_name=%s rr_type=%d rr_class=%d ttl=%d\n",
66 hdr,
67 nmb_namestr(&res->rr_name),
68 res->rr_type,
69 res->rr_class,
70 res->ttl ) );
72 if (res->rdlength == 0) {
73 return;
76 for (i = 0; i < res->rdlength; i+= MAX_NETBIOSNAME_LEN) {
77 DEBUGADD(4, (" %s %3x char ", hdr, i));
79 for (j = 0; j < MAX_NETBIOSNAME_LEN; j++) {
80 unsigned char x = res->rdata[i+j];
81 if (x < 32 || x > 127)
82 x = '.';
84 if (i+j >= res->rdlength)
85 break;
86 DEBUGADD(4, ("%c", x));
89 DEBUGADD(4, (" hex "));
91 for (j = 0; j < MAX_NETBIOSNAME_LEN; j++) {
92 if (i+j >= res->rdlength)
93 break;
94 DEBUGADD(4, ("%02X", (unsigned char)res->rdata[i+j]));
97 DEBUGADD(4, ("\n"));
101 /****************************************************************************
102 Process a nmb packet.
103 ****************************************************************************/
105 void debug_nmb_packet(struct packet_struct *p)
107 struct nmb_packet *nmb = &p->packet.nmb;
109 if( DEBUGLVL( 4 ) ) {
110 dbgtext( "nmb packet from %s(%d) header: id=%d "
111 "opcode=%s(%d) response=%s\n",
112 inet_ntoa(p->ip), p->port,
113 nmb->header.name_trn_id,
114 lookup_opcode_name(nmb->header.opcode),
115 nmb->header.opcode,
116 BOOLSTR(nmb->header.response) );
117 dbgtext( " header: flags: bcast=%s rec_avail=%s "
118 "rec_des=%s trunc=%s auth=%s\n",
119 BOOLSTR(nmb->header.nm_flags.bcast),
120 BOOLSTR(nmb->header.nm_flags.recursion_available),
121 BOOLSTR(nmb->header.nm_flags.recursion_desired),
122 BOOLSTR(nmb->header.nm_flags.trunc),
123 BOOLSTR(nmb->header.nm_flags.authoritative) );
124 dbgtext( " header: rcode=%d qdcount=%d ancount=%d "
125 "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 if (*offset > length - 2) {
165 return False;
167 (*offset) = ((ubuf[*offset] & ~0xC0)<<8) | ubuf[(*offset)+1];
168 if (loop_count++ == 10 ||
169 (*offset) < 0 || (*offset)>(length-2)) {
170 return False;
173 return True;
176 /*******************************************************************
177 Parse a nmb name from "compressed" format to something readable
178 return the space taken by the name, or 0 if the name is invalid
179 ******************************************************************/
181 static int parse_nmb_name(char *inbuf,int ofs,int length, struct nmb_name *name)
183 size_t m,n=0;
184 unsigned char *ubuf = (unsigned char *)inbuf;
185 int ret = 0;
186 bool got_pointer=False;
187 size_t loop_count=0;
188 int offset = ofs;
190 if (length - offset < 2)
191 return(0);
193 /* handle initial name pointers */
194 if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret))
195 return(0);
197 m = ubuf[offset];
199 /* m must be 32 to exactly fill in the 16 bytes of the netbios name */
200 if (m != 32) {
201 return 0;
203 /* Cannot go past length. */
204 if (offset+m+2 > length) {
205 return 0;
208 memset((char *)name,'\0',sizeof(*name));
210 /* the "compressed" part */
211 if (!got_pointer)
212 ret += m + 2;
213 offset++;
214 while (m > 0) {
215 unsigned char c1,c2;
216 c1 = ubuf[offset++]-'A';
217 c2 = ubuf[offset++]-'A';
218 if ((c1 & 0xF0) || (c2 & 0xF0)) {
219 return(0);
221 if (n >= sizeof(name->name)) {
222 return 0;
224 name->name[n++] = (c1<<4) | c2;
225 m -= 2;
228 * RFC1002: For a valid NetBIOS name, exiting from the above,
229 * n *must* be MAX_NETBIOSNAME_LEN (16).
231 if (n != MAX_NETBIOSNAME_LEN) {
232 return 0;
235 /* parse out the name type, its always
236 * in the 16th byte of the name */
237 name->name_type = ((unsigned char)name->name[15]) & 0xff;
239 /* remove trailing spaces */
240 name->name[15] = 0;
241 n = 14;
242 while (n && name->name[n]==' ')
243 name->name[n--] = 0;
245 /* now the domain parts (if any) */
246 n = 0;
247 while (ubuf[offset]) {
248 /* we can have pointers within the domain part as well */
249 if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret))
250 return(0);
252 m = ubuf[offset];
254 * Don't allow null domain parts.
256 if (!m)
257 return(0);
258 if (!got_pointer)
259 ret += m+1;
260 if (n)
261 name->scope[n++] = '.';
262 if (m+2+offset>length || n+m+1>sizeof(name->scope))
263 return(0);
264 offset++;
265 while (m--)
266 name->scope[n++] = (char)ubuf[offset++];
269 * Watch for malicious loops.
271 if (loop_count++ == 10)
272 return 0;
274 name->scope[n++] = 0;
276 return(ret);
279 /****************************************************************************
280 Put a netbios name, padding(s) and a name type into a 16 character buffer.
281 name is already in DOS charset.
282 [15 bytes name + padding][1 byte name type].
283 ****************************************************************************/
285 void put_name(char *dest, const char *name, int pad, unsigned int name_type)
287 size_t len = strlen(name);
289 memcpy(dest, name, (len < MAX_NETBIOSNAME_LEN) ?
290 len : MAX_NETBIOSNAME_LEN - 1);
291 if (len < MAX_NETBIOSNAME_LEN - 1) {
292 memset(dest + len, pad, MAX_NETBIOSNAME_LEN - 1 - len);
294 dest[MAX_NETBIOSNAME_LEN - 1] = name_type;
297 /*******************************************************************
298 Put a compressed nmb name into a buffer. Return the length of the
299 compressed name.
301 Compressed names are really weird. The "compression" doubles the
302 size. The idea is that it also means that compressed names conform
303 to the domain name system. See RFC1002.
305 If buf == NULL this is a length calculation.
306 ******************************************************************/
308 static int put_nmb_name(char *buf, size_t buflen, int offset,struct nmb_name *name)
310 int ret,m;
311 nstring buf1;
312 char *p;
314 if (strcmp(name->name,"*") == 0) {
315 /* special case for wildcard name */
316 put_name(buf1, "*", '\0', name->name_type);
317 } else {
318 put_name(buf1, name->name, ' ', name->name_type);
321 if (buf) {
322 if (offset >= buflen) {
323 return 0;
325 buf[offset] = 0x20;
328 ret = 34;
330 for (m=0;m<MAX_NETBIOSNAME_LEN;m++) {
331 if (buf) {
332 if (offset+2+2*m >= buflen) {
333 return 0;
335 buf[offset+1+2*m] = 'A' + ((buf1[m]>>4)&0xF);
336 buf[offset+2+2*m] = 'A' + (buf1[m]&0xF);
339 offset += 33;
341 if (buf) {
342 if (offset >= buflen) {
343 return 0;
345 buf[offset] = 0;
348 if (name->scope[0]) {
349 /* XXXX this scope handling needs testing */
350 size_t scopenamelen = strlen(name->scope) + 1;
351 ret += scopenamelen;
352 if (buf) {
353 if (offset+1+scopenamelen >= buflen) {
354 return 0;
356 strlcpy(&buf[offset+1],name->scope,
357 buflen - (offset+1));
359 p = &buf[offset+1];
360 while ((p = strchr_m(p,'.'))) {
361 buf[offset] = PTR_DIFF(p,&buf[offset+1]);
362 offset += (buf[offset] + 1);
363 if (offset+1 >= buflen) {
364 return 0;
366 p = &buf[offset+1];
368 buf[offset] = strlen(&buf[offset+1]);
372 return ret;
375 /*******************************************************************
376 Useful for debugging messages.
377 ******************************************************************/
379 char *nmb_namestr(const struct nmb_name *n)
381 fstring name;
382 char *result;
384 pull_ascii_fstring(name, n->name);
385 if (!n->scope[0])
386 result = talloc_asprintf(talloc_tos(), "%s<%02x>", name,
387 n->name_type);
388 else
389 result = talloc_asprintf(talloc_tos(), "%s<%02x>.%s", name,
390 n->name_type, n->scope);
392 SMB_ASSERT(result != NULL);
393 return result;
396 /*******************************************************************
397 Allocate and parse some resource records.
398 ******************************************************************/
400 static bool parse_alloc_res_rec(char *inbuf,int *offset,int length,
401 struct res_rec **recs, int count)
403 int i;
405 *recs = SMB_MALLOC_ARRAY(struct res_rec, count);
406 if (!*recs)
407 return(False);
409 memset((char *)*recs,'\0',sizeof(**recs)*count);
411 for (i=0;i<count;i++) {
412 int l = parse_nmb_name(inbuf,*offset,length,
413 &(*recs)[i].rr_name);
414 (*offset) += l;
415 if (!l || (*offset)+10 > length) {
416 SAFE_FREE(*recs);
417 return(False);
419 (*recs)[i].rr_type = RSVAL(inbuf,(*offset));
420 (*recs)[i].rr_class = RSVAL(inbuf,(*offset)+2);
421 (*recs)[i].ttl = RIVAL(inbuf,(*offset)+4);
422 (*recs)[i].rdlength = RSVAL(inbuf,(*offset)+8);
423 (*offset) += 10;
424 if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) ||
425 (*offset)+(*recs)[i].rdlength > length) {
426 SAFE_FREE(*recs);
427 return(False);
429 memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength);
430 (*offset) += (*recs)[i].rdlength;
432 return(True);
435 /*******************************************************************
436 Put a resource record into a packet.
437 If buf == NULL this is a length calculation.
438 ******************************************************************/
440 static int put_res_rec(char *buf, size_t buflen, int offset,struct res_rec *recs,int count)
442 int ret=0;
443 int i;
445 for (i=0;i<count;i++) {
446 int l = put_nmb_name(buf,buflen,offset,&recs[i].rr_name);
447 offset += l;
448 ret += l;
449 if (buf) {
450 RSSVAL(buf,offset,recs[i].rr_type);
451 RSSVAL(buf,offset+2,recs[i].rr_class);
452 RSIVAL(buf,offset+4,(unsigned int)recs[i].ttl);
453 RSSVAL(buf,offset+8,recs[i].rdlength);
454 memcpy(buf+offset+10,recs[i].rdata,recs[i].rdlength);
456 offset += 10+recs[i].rdlength;
457 ret += 10+recs[i].rdlength;
460 return ret;
463 /*******************************************************************
464 Put a compressed name pointer record into a packet.
465 If buf == NULL this is a length calculation.
466 ******************************************************************/
468 static int put_compressed_name_ptr(unsigned char *buf,
469 int offset,
470 struct res_rec *rec,
471 int ptr_offset)
473 int ret=offset;
474 if (buf) {
475 buf[offset] = (0xC0 | ((ptr_offset >> 8) & 0xFF));
476 buf[offset+1] = (ptr_offset & 0xFF);
478 offset += 2;
479 if (buf) {
480 RSSVAL(buf,offset,rec->rr_type);
481 RSSVAL(buf,offset+2,rec->rr_class);
482 RSIVAL(buf,offset+4,rec->ttl);
483 RSSVAL(buf,offset+8,rec->rdlength);
484 memcpy(buf+offset+10,rec->rdata,rec->rdlength);
486 offset += 10+rec->rdlength;
487 ret = (offset - ret);
489 return ret;
492 /*******************************************************************
493 Parse a dgram packet. Return False if the packet can't be parsed
494 or is invalid for some reason, True otherwise.
496 This is documented in section 4.4.1 of RFC1002.
497 ******************************************************************/
499 static bool parse_dgram(char *inbuf,int length,struct dgram_packet *dgram)
501 size_t offset;
502 int flags;
504 memset((char *)dgram,'\0',sizeof(*dgram));
506 if (length < 14)
507 return(False);
509 dgram->header.msg_type = CVAL(inbuf,0);
510 flags = CVAL(inbuf,1);
511 dgram->header.flags.node_type = (enum node_type)((flags>>2)&3);
512 if (flags & 1)
513 dgram->header.flags.more = True;
514 if (flags & 2)
515 dgram->header.flags.first = True;
516 dgram->header.dgm_id = RSVAL(inbuf,2);
517 putip((char *)&dgram->header.source_ip,inbuf+4);
518 dgram->header.source_port = RSVAL(inbuf,8);
519 dgram->header.dgm_length = RSVAL(inbuf,10);
520 dgram->header.packet_offset = RSVAL(inbuf,12);
522 offset = 14;
524 if (dgram->header.msg_type == 0x10 ||
525 dgram->header.msg_type == 0x11 ||
526 dgram->header.msg_type == 0x12) {
527 offset += parse_nmb_name(inbuf,offset,length,
528 &dgram->source_name);
529 offset += parse_nmb_name(inbuf,offset,length,
530 &dgram->dest_name);
533 if (offset >= length || (length-offset > sizeof(dgram->data)))
534 return(False);
536 dgram->datasize = length-offset;
537 memcpy(dgram->data,inbuf+offset,dgram->datasize);
539 /* Paranioa. Ensure the last 2 bytes in the dgram buffer are
540 zero. This should be true anyway, just enforce it for
541 paranioa sake. JRA. */
542 SMB_ASSERT(dgram->datasize <= (sizeof(dgram->data)-2));
543 memset(&dgram->data[sizeof(dgram->data)-2], '\0', 2);
545 return(True);
548 /*******************************************************************
549 Parse a nmb packet. Return False if the packet can't be parsed
550 or is invalid for some reason, True otherwise.
551 ******************************************************************/
553 static bool parse_nmb(char *inbuf,int length,struct nmb_packet *nmb)
555 int nm_flags,offset;
557 memset((char *)nmb,'\0',sizeof(*nmb));
559 if (length < 12)
560 return(False);
562 /* parse the header */
563 nmb->header.name_trn_id = RSVAL(inbuf,0);
565 DEBUG(10,("parse_nmb: packet id = %d\n", nmb->header.name_trn_id));
567 nmb->header.opcode = (CVAL(inbuf,2) >> 3) & 0xF;
568 nmb->header.response = ((CVAL(inbuf,2)>>7)&1)?True:False;
569 nm_flags = ((CVAL(inbuf,2) & 0x7) << 4) + (CVAL(inbuf,3)>>4);
570 nmb->header.nm_flags.bcast = (nm_flags&1)?True:False;
571 nmb->header.nm_flags.recursion_available = (nm_flags&8)?True:False;
572 nmb->header.nm_flags.recursion_desired = (nm_flags&0x10)?True:False;
573 nmb->header.nm_flags.trunc = (nm_flags&0x20)?True:False;
574 nmb->header.nm_flags.authoritative = (nm_flags&0x40)?True:False;
575 nmb->header.rcode = CVAL(inbuf,3) & 0xF;
576 nmb->header.qdcount = RSVAL(inbuf,4);
577 nmb->header.ancount = RSVAL(inbuf,6);
578 nmb->header.nscount = RSVAL(inbuf,8);
579 nmb->header.arcount = RSVAL(inbuf,10);
581 if (nmb->header.qdcount) {
582 offset = parse_nmb_name(inbuf,12,length,
583 &nmb->question.question_name);
584 if (!offset)
585 return(False);
587 if (length - (12+offset) < 4)
588 return(False);
589 nmb->question.question_type = RSVAL(inbuf,12+offset);
590 nmb->question.question_class = RSVAL(inbuf,12+offset+2);
592 offset += 12+4;
593 } else {
594 offset = 12;
597 /* and any resource records */
598 if (nmb->header.ancount &&
599 !parse_alloc_res_rec(inbuf,&offset,length,&nmb->answers,
600 nmb->header.ancount))
601 return(False);
603 if (nmb->header.nscount &&
604 !parse_alloc_res_rec(inbuf,&offset,length,&nmb->nsrecs,
605 nmb->header.nscount))
606 return(False);
608 if (nmb->header.arcount &&
609 !parse_alloc_res_rec(inbuf,&offset,length,
610 &nmb->additional, nmb->header.arcount))
611 return(False);
613 return(True);
616 /*******************************************************************
617 'Copy constructor' for an nmb packet.
618 ******************************************************************/
620 static struct packet_struct *copy_nmb_packet(struct packet_struct *packet)
622 struct nmb_packet *nmb;
623 struct nmb_packet *copy_nmb;
624 struct packet_struct *pkt_copy;
626 if(( pkt_copy = SMB_MALLOC_P(struct packet_struct)) == NULL) {
627 DEBUG(0,("copy_nmb_packet: malloc fail.\n"));
628 return NULL;
631 /* Structure copy of entire thing. */
633 *pkt_copy = *packet;
635 /* Ensure this copy is not locked. */
636 pkt_copy->locked = False;
637 pkt_copy->recv_fd = -1;
638 pkt_copy->send_fd = -1;
640 /* Ensure this copy has no resource records. */
641 nmb = &packet->packet.nmb;
642 copy_nmb = &pkt_copy->packet.nmb;
644 copy_nmb->answers = NULL;
645 copy_nmb->nsrecs = NULL;
646 copy_nmb->additional = NULL;
648 /* Now copy any resource records. */
650 if (nmb->answers) {
651 if((copy_nmb->answers = SMB_MALLOC_ARRAY(
652 struct res_rec,nmb->header.ancount)) == NULL)
653 goto free_and_exit;
654 memcpy((char *)copy_nmb->answers, (char *)nmb->answers,
655 nmb->header.ancount * sizeof(struct res_rec));
657 if (nmb->nsrecs) {
658 if((copy_nmb->nsrecs = SMB_MALLOC_ARRAY(
659 struct res_rec, nmb->header.nscount)) == NULL)
660 goto free_and_exit;
661 memcpy((char *)copy_nmb->nsrecs, (char *)nmb->nsrecs,
662 nmb->header.nscount * sizeof(struct res_rec));
664 if (nmb->additional) {
665 if((copy_nmb->additional = SMB_MALLOC_ARRAY(
666 struct res_rec, nmb->header.arcount)) == NULL)
667 goto free_and_exit;
668 memcpy((char *)copy_nmb->additional, (char *)nmb->additional,
669 nmb->header.arcount * sizeof(struct res_rec));
672 return pkt_copy;
674 free_and_exit:
676 SAFE_FREE(copy_nmb->answers);
677 SAFE_FREE(copy_nmb->nsrecs);
678 SAFE_FREE(copy_nmb->additional);
679 SAFE_FREE(pkt_copy);
681 DEBUG(0,("copy_nmb_packet: malloc fail in resource records.\n"));
682 return NULL;
685 /*******************************************************************
686 'Copy constructor' for a dgram packet.
687 ******************************************************************/
689 static struct packet_struct *copy_dgram_packet(struct packet_struct *packet)
691 struct packet_struct *pkt_copy;
693 if(( pkt_copy = SMB_MALLOC_P(struct packet_struct)) == NULL) {
694 DEBUG(0,("copy_dgram_packet: malloc fail.\n"));
695 return NULL;
698 /* Structure copy of entire thing. */
700 *pkt_copy = *packet;
702 /* Ensure this copy is not locked. */
703 pkt_copy->locked = False;
704 pkt_copy->recv_fd = -1;
705 pkt_copy->send_fd = -1;
707 /* There are no additional pointers in a dgram packet,
708 we are finished. */
709 return pkt_copy;
712 /*******************************************************************
713 'Copy constructor' for a generic packet.
714 ******************************************************************/
716 struct packet_struct *copy_packet(struct packet_struct *packet)
718 if(packet->packet_type == NMB_PACKET)
719 return copy_nmb_packet(packet);
720 else if (packet->packet_type == DGRAM_PACKET)
721 return copy_dgram_packet(packet);
722 return NULL;
725 /*******************************************************************
726 Free up any resources associated with an nmb packet.
727 ******************************************************************/
729 static void free_nmb_packet(struct nmb_packet *nmb)
731 SAFE_FREE(nmb->answers);
732 SAFE_FREE(nmb->nsrecs);
733 SAFE_FREE(nmb->additional);
736 /*******************************************************************
737 Free up any resources associated with a dgram packet.
738 ******************************************************************/
740 static void free_dgram_packet(struct dgram_packet *nmb)
742 /* We have nothing to do for a dgram packet. */
745 /*******************************************************************
746 Free up any resources associated with a packet.
747 ******************************************************************/
749 void free_packet(struct packet_struct *packet)
751 if (packet->locked)
752 return;
753 if (packet->packet_type == NMB_PACKET)
754 free_nmb_packet(&packet->packet.nmb);
755 else if (packet->packet_type == DGRAM_PACKET)
756 free_dgram_packet(&packet->packet.dgram);
757 ZERO_STRUCTPN(packet);
758 SAFE_FREE(packet);
761 int packet_trn_id(struct packet_struct *p)
763 int result;
764 switch (p->packet_type) {
765 case NMB_PACKET:
766 result = p->packet.nmb.header.name_trn_id;
767 break;
768 case DGRAM_PACKET:
769 result = p->packet.dgram.header.dgm_id;
770 break;
771 default:
772 result = -1;
774 return result;
777 /*******************************************************************
778 Parse a packet buffer into a packet structure.
779 ******************************************************************/
781 struct packet_struct *parse_packet(char *buf,int length,
782 enum packet_type packet_type,
783 struct in_addr ip,
784 int port)
786 struct packet_struct *p;
787 bool ok=False;
789 p = SMB_MALLOC_P(struct packet_struct);
790 if (!p)
791 return(NULL);
793 ZERO_STRUCTP(p); /* initialize for possible padding */
795 p->next = NULL;
796 p->prev = NULL;
797 p->ip = ip;
798 p->port = port;
799 p->locked = False;
800 p->timestamp = time(NULL);
801 p->packet_type = packet_type;
803 switch (packet_type) {
804 case NMB_PACKET:
805 ok = parse_nmb(buf,length,&p->packet.nmb);
806 break;
808 case DGRAM_PACKET:
809 ok = parse_dgram(buf,length,&p->packet.dgram);
810 break;
813 if (!ok) {
814 free_packet(p);
815 return NULL;
818 return p;
821 static struct packet_struct *copy_packet_talloc(
822 TALLOC_CTX *mem_ctx, const struct packet_struct *src)
824 struct packet_struct *pkt;
826 pkt = talloc_memdup(mem_ctx, src, sizeof(struct packet_struct));
827 if (pkt == NULL) {
828 return NULL;
830 pkt->locked = false;
831 pkt->recv_fd = -1;
832 pkt->send_fd = -1;
834 if (src->packet_type == NMB_PACKET) {
835 const struct nmb_packet *nsrc = &src->packet.nmb;
836 struct nmb_packet *ndst = &pkt->packet.nmb;
838 if (nsrc->answers != NULL) {
839 ndst->answers = talloc_memdup(
840 pkt, nsrc->answers,
841 sizeof(struct res_rec) * nsrc->header.ancount);
842 if (ndst->answers == NULL) {
843 goto fail;
846 if (nsrc->nsrecs != NULL) {
847 ndst->nsrecs = talloc_memdup(
848 pkt, nsrc->nsrecs,
849 sizeof(struct res_rec) * nsrc->header.nscount);
850 if (ndst->nsrecs == NULL) {
851 goto fail;
854 if (nsrc->additional != NULL) {
855 ndst->additional = talloc_memdup(
856 pkt, nsrc->additional,
857 sizeof(struct res_rec) * nsrc->header.arcount);
858 if (ndst->additional == NULL) {
859 goto fail;
864 return pkt;
867 * DGRAM packets have no substructures
870 fail:
871 TALLOC_FREE(pkt);
872 return NULL;
875 struct packet_struct *parse_packet_talloc(TALLOC_CTX *mem_ctx,
876 char *buf,int length,
877 enum packet_type packet_type,
878 struct in_addr ip,
879 int port)
881 struct packet_struct *pkt, *result;
883 pkt = parse_packet(buf, length, packet_type, ip, port);
884 if (pkt == NULL) {
885 return NULL;
887 result = copy_packet_talloc(mem_ctx, pkt);
888 free_packet(pkt);
889 return result;
892 /*******************************************************************
893 Send a udp packet on a already open socket.
894 ******************************************************************/
896 static bool send_udp(int fd,char *buf,int len,struct in_addr ip,int port)
898 bool ret = False;
899 int i;
900 struct sockaddr_in sock_out;
902 /* set the address and port */
903 memset((char *)&sock_out,'\0',sizeof(sock_out));
904 putip((char *)&sock_out.sin_addr,(char *)&ip);
905 sock_out.sin_port = htons( port );
906 sock_out.sin_family = AF_INET;
908 DEBUG( 5, ( "Sending a packet of len %d to (%s) on port %d\n",
909 len, inet_ntoa(ip), port ) );
912 * Patch to fix asynch error notifications from Linux kernel.
915 for (i = 0; i < 5; i++) {
916 ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out,
917 sizeof(sock_out)) >= 0);
918 if (ret || errno != ECONNREFUSED)
919 break;
922 if (!ret)
923 DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n",
924 inet_ntoa(ip),port,strerror(errno)));
926 return(ret);
929 /*******************************************************************
930 Build a dgram packet ready for sending.
931 If buf == NULL this is a length calculation.
932 ******************************************************************/
934 static int build_dgram(char *buf, size_t len, struct dgram_packet *dgram)
936 unsigned char *ubuf = (unsigned char *)buf;
937 int offset=0;
939 /* put in the header */
940 if (buf) {
941 ubuf[0] = dgram->header.msg_type;
942 ubuf[1] = (((int)dgram->header.flags.node_type)<<2);
943 if (dgram->header.flags.more)
944 ubuf[1] |= 1;
945 if (dgram->header.flags.first)
946 ubuf[1] |= 2;
947 RSSVAL(ubuf,2,dgram->header.dgm_id);
948 putip(ubuf+4,(char *)&dgram->header.source_ip);
949 RSSVAL(ubuf,8,dgram->header.source_port);
950 RSSVAL(ubuf,12,dgram->header.packet_offset);
953 offset = 14;
955 if (dgram->header.msg_type == 0x10 ||
956 dgram->header.msg_type == 0x11 ||
957 dgram->header.msg_type == 0x12) {
958 offset += put_nmb_name((char *)ubuf,len,offset,&dgram->source_name);
959 offset += put_nmb_name((char *)ubuf,len,offset,&dgram->dest_name);
962 if (buf) {
963 memcpy(ubuf+offset,dgram->data,dgram->datasize);
965 offset += dgram->datasize;
967 /* automatically set the dgm_length
968 * NOTE: RFC1002 says the dgm_length does *not*
969 * include the fourteen-byte header. crh
971 dgram->header.dgm_length = (offset - 14);
972 if (buf) {
973 RSSVAL(ubuf,10,dgram->header.dgm_length);
976 return offset;
979 /*******************************************************************
980 Build a nmb name
981 *******************************************************************/
983 void make_nmb_name( struct nmb_name *n, const char *name, int type)
985 fstring unix_name;
986 memset( (char *)n, '\0', sizeof(struct nmb_name) );
987 fstrcpy(unix_name, name);
988 (void)strupper_m(unix_name);
989 push_ascii(n->name, unix_name, sizeof(n->name), STR_TERMINATE);
990 n->name_type = (unsigned int)type & 0xFF;
991 push_ascii(n->scope, lp_netbios_scope(), 64, STR_TERMINATE);
994 /*******************************************************************
995 Compare two nmb names
996 ******************************************************************/
998 bool nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2)
1000 return ((n1->name_type == n2->name_type) &&
1001 strequal(n1->name ,n2->name ) &&
1002 strequal(n1->scope,n2->scope));
1005 /*******************************************************************
1006 Build a nmb packet ready for sending.
1007 If buf == NULL this is a length calculation.
1008 ******************************************************************/
1010 static int build_nmb(char *buf, size_t len, struct nmb_packet *nmb)
1012 unsigned char *ubuf = (unsigned char *)buf;
1013 int offset=0;
1015 if (len && len < 12) {
1016 return 0;
1019 /* put in the header */
1020 if (buf) {
1021 RSSVAL(ubuf,offset,nmb->header.name_trn_id);
1022 ubuf[offset+2] = (nmb->header.opcode & 0xF) << 3;
1023 if (nmb->header.response)
1024 ubuf[offset+2] |= (1<<7);
1025 if (nmb->header.nm_flags.authoritative &&
1026 nmb->header.response)
1027 ubuf[offset+2] |= 0x4;
1028 if (nmb->header.nm_flags.trunc)
1029 ubuf[offset+2] |= 0x2;
1030 if (nmb->header.nm_flags.recursion_desired)
1031 ubuf[offset+2] |= 0x1;
1032 if (nmb->header.nm_flags.recursion_available &&
1033 nmb->header.response)
1034 ubuf[offset+3] |= 0x80;
1035 if (nmb->header.nm_flags.bcast)
1036 ubuf[offset+3] |= 0x10;
1037 ubuf[offset+3] |= (nmb->header.rcode & 0xF);
1039 RSSVAL(ubuf,offset+4,nmb->header.qdcount);
1040 RSSVAL(ubuf,offset+6,nmb->header.ancount);
1041 RSSVAL(ubuf,offset+8,nmb->header.nscount);
1042 RSSVAL(ubuf,offset+10,nmb->header.arcount);
1045 offset += 12;
1046 if (nmb->header.qdcount) {
1047 /* XXXX this doesn't handle a qdcount of > 1 */
1048 if (len) {
1049 /* Length check. */
1050 int extra = put_nmb_name(NULL,0,offset,
1051 &nmb->question.question_name);
1052 if (offset + extra > len) {
1053 return 0;
1056 offset += put_nmb_name((char *)ubuf,len,offset,
1057 &nmb->question.question_name);
1058 if (buf) {
1059 RSSVAL(ubuf,offset,nmb->question.question_type);
1060 RSSVAL(ubuf,offset+2,nmb->question.question_class);
1062 offset += 4;
1065 if (nmb->header.ancount) {
1066 if (len) {
1067 /* Length check. */
1068 int extra = put_res_rec(NULL,0,offset,nmb->answers,
1069 nmb->header.ancount);
1070 if (offset + extra > len) {
1071 return 0;
1074 offset += put_res_rec((char *)ubuf,len,offset,nmb->answers,
1075 nmb->header.ancount);
1078 if (nmb->header.nscount) {
1079 if (len) {
1080 /* Length check. */
1081 int extra = put_res_rec(NULL,0,offset,nmb->nsrecs,
1082 nmb->header.nscount);
1083 if (offset + extra > len) {
1084 return 0;
1087 offset += put_res_rec((char *)ubuf,len,offset,nmb->nsrecs,
1088 nmb->header.nscount);
1092 * The spec says we must put compressed name pointers
1093 * in the following outgoing packets :
1094 * NAME_REGISTRATION_REQUEST, NAME_REFRESH_REQUEST,
1095 * NAME_RELEASE_REQUEST.
1098 if((nmb->header.response == False) &&
1099 ((nmb->header.opcode == NMB_NAME_REG_OPCODE) ||
1100 (nmb->header.opcode == NMB_NAME_RELEASE_OPCODE) ||
1101 (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_8) ||
1102 (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_9) ||
1103 (nmb->header.opcode == NMB_NAME_MULTIHOMED_REG_OPCODE)) &&
1104 (nmb->header.arcount == 1)) {
1106 if (len) {
1107 /* Length check. */
1108 int extra = put_compressed_name_ptr(NULL,offset,
1109 nmb->additional,12);
1110 if (offset + extra > len) {
1111 return 0;
1114 offset += put_compressed_name_ptr(ubuf,offset,
1115 nmb->additional,12);
1116 } else if (nmb->header.arcount) {
1117 if (len) {
1118 /* Length check. */
1119 int extra = put_res_rec(NULL,0,offset,nmb->additional,
1120 nmb->header.arcount);
1121 if (offset + extra > len) {
1122 return 0;
1125 offset += put_res_rec((char *)ubuf,len,offset,nmb->additional,
1126 nmb->header.arcount);
1128 return offset;
1131 /*******************************************************************
1132 Linearise a packet.
1133 ******************************************************************/
1135 int build_packet(char *buf, size_t buflen, struct packet_struct *p)
1137 int len = 0;
1139 switch (p->packet_type) {
1140 case NMB_PACKET:
1141 len = build_nmb(buf,buflen,&p->packet.nmb);
1142 break;
1144 case DGRAM_PACKET:
1145 len = build_dgram(buf,buflen,&p->packet.dgram);
1146 break;
1149 return len;
1152 /*******************************************************************
1153 Send a packet_struct.
1154 ******************************************************************/
1156 bool send_packet(struct packet_struct *p)
1158 char buf[1024];
1159 int len=0;
1161 memset(buf,'\0',sizeof(buf));
1163 len = build_packet(buf, sizeof(buf), p);
1165 if (!len)
1166 return(False);
1168 return(send_udp(p->send_fd,buf,len,p->ip,p->port));
1171 /****************************************************************************
1172 Receive a UDP/138 packet either via UDP or from the unexpected packet
1173 queue. The packet must be a reply packet and have the specified mailslot name
1174 The timeout is in milliseconds.
1175 ***************************************************************************/
1177 /****************************************************************************
1178 See if a datagram has the right mailslot name.
1179 ***************************************************************************/
1181 bool match_mailslot_name(struct packet_struct *p, const char *mailslot_name)
1183 struct dgram_packet *dgram = &p->packet.dgram;
1184 char *buf;
1186 buf = &dgram->data[0];
1187 buf -= 4;
1189 buf = smb_buf(buf);
1191 if (memcmp(buf, mailslot_name, strlen(mailslot_name)+1) == 0) {
1192 return True;
1195 return False;
1198 /****************************************************************************
1199 Return the number of bits that match between two len character buffers
1200 ***************************************************************************/
1202 int matching_len_bits(const unsigned char *p1, const unsigned char *p2, size_t len)
1204 size_t i, j;
1205 int ret = 0;
1206 for (i=0; i<len; i++) {
1207 if (p1[i] != p2[i])
1208 break;
1209 ret += 8;
1212 if (i==len)
1213 return ret;
1215 for (j=0; j<8; j++) {
1216 if ((p1[i] & (1<<(7-j))) != (p2[i] & (1<<(7-j))))
1217 break;
1218 ret++;
1221 return ret;
1224 static unsigned char sort_ip[4];
1226 /****************************************************************************
1227 Compare two query reply records.
1228 ***************************************************************************/
1230 static int name_query_comp(unsigned char *p1, unsigned char *p2)
1232 return matching_len_bits(p2+2, sort_ip, 4) -
1233 matching_len_bits(p1+2, sort_ip, 4);
1236 /****************************************************************************
1237 Sort a set of 6 byte name query response records so that the IPs that
1238 have the most leading bits in common with the specified address come first.
1239 ***************************************************************************/
1241 void sort_query_replies(char *data, int n, struct in_addr ip)
1243 if (n <= 1)
1244 return;
1246 putip(sort_ip, (char *)&ip);
1248 /* TODO:
1249 this can't use TYPESAFE_QSORT() as the types are wrong.
1250 It should be fixed to use a real type instead of char*
1252 qsort(data, n, 6, QSORT_CAST name_query_comp);
1255 /****************************************************************************
1256 Interpret the weird netbios "name" into a unix fstring. Return the name type.
1257 Returns -1 on error.
1258 ****************************************************************************/
1260 static int name_interpret(unsigned char *buf, size_t buf_len,
1261 unsigned char *in, fstring name)
1263 unsigned char *end_ptr = buf + buf_len;
1264 int ret;
1265 unsigned int len;
1266 fstring out_string;
1267 unsigned char *out = (unsigned char *)out_string;
1269 *out=0;
1271 if (in >= end_ptr) {
1272 return -1;
1274 len = (*in++) / 2;
1276 if (len<1) {
1277 return -1;
1280 while (len--) {
1281 if (&in[1] >= end_ptr) {
1282 return -1;
1284 if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
1285 *out = 0;
1286 return(0);
1288 *out = ((in[0]-'A')<<4) + (in[1]-'A');
1289 in += 2;
1290 out++;
1291 if (PTR_DIFF(out,out_string) >= sizeof(fstring)) {
1292 return -1;
1295 ret = out[-1];
1296 out[-1] = 0;
1298 pull_ascii_fstring(name, out_string);
1300 return(ret);
1303 /****************************************************************************
1304 Mangle a name into netbios format.
1305 Note: <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
1306 ****************************************************************************/
1308 char *name_mangle(TALLOC_CTX *mem_ctx, const char *In, char name_type)
1310 int i;
1311 int len;
1312 nstring buf;
1313 char *result;
1314 char *p;
1316 result = talloc_array(mem_ctx, char, 33 + strlen(lp_netbios_scope()) + 2);
1317 if (result == NULL) {
1318 return NULL;
1320 p = result;
1322 /* Safely copy the input string, In, into buf[]. */
1323 if (strcmp(In,"*") == 0)
1324 put_name(buf, "*", '\0', 0x00);
1325 else {
1326 /* We use an fstring here as mb dos names can expend x3 when
1327 going to utf8. */
1328 fstring buf_unix;
1329 nstring buf_dos;
1331 pull_ascii_fstring(buf_unix, In);
1332 if (!strupper_m(buf_unix)) {
1333 return NULL;
1336 push_ascii_nstring(buf_dos, buf_unix);
1337 put_name(buf, buf_dos, ' ', name_type);
1340 /* Place the length of the first field into the output buffer. */
1341 p[0] = 32;
1342 p++;
1344 /* Now convert the name to the rfc1001/1002 format. */
1345 for( i = 0; i < MAX_NETBIOSNAME_LEN; i++ ) {
1346 p[i*2] = ( (buf[i] >> 4) & 0x000F ) + 'A';
1347 p[(i*2)+1] = (buf[i] & 0x000F) + 'A';
1349 p += 32;
1350 p[0] = '\0';
1352 /* Add the scope string. */
1353 for( i = 0, len = 0; *(lp_netbios_scope()) != '\0'; i++, len++ ) {
1354 switch( (lp_netbios_scope())[i] ) {
1355 case '\0':
1356 p[0] = len;
1357 if( len > 0 )
1358 p[len+1] = 0;
1359 return result;
1360 case '.':
1361 p[0] = len;
1362 p += (len + 1);
1363 len = -1;
1364 break;
1365 default:
1366 p[len+1] = (lp_netbios_scope())[i];
1367 break;
1371 return result;
1374 /****************************************************************************
1375 Find a pointer to a netbios name.
1376 ****************************************************************************/
1378 static unsigned char *name_ptr(unsigned char *buf, size_t buf_len, unsigned int ofs)
1380 unsigned char c = 0;
1382 if (ofs > buf_len || buf_len < 1) {
1383 return NULL;
1386 c = *(unsigned char *)(buf+ofs);
1387 if ((c & 0xC0) == 0xC0) {
1388 uint16_t l = 0;
1390 if (ofs > buf_len - 1) {
1391 return NULL;
1393 l = RSVAL(buf, ofs) & 0x3FFF;
1394 if (l > buf_len) {
1395 return NULL;
1397 DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
1398 return(buf + l);
1399 } else {
1400 return(buf+ofs);
1404 /****************************************************************************
1405 Extract a netbios name from a buf (into a unix string) return name type.
1406 Returns -1 on error.
1407 ****************************************************************************/
1409 int name_extract(unsigned char *buf, size_t buf_len, unsigned int ofs, fstring name)
1411 unsigned char *p = name_ptr(buf,buf_len,ofs);
1413 name[0] = '\0';
1414 if (p == NULL) {
1415 return -1;
1417 return(name_interpret(buf,buf_len,p,name));
1420 /****************************************************************************
1421 Return the total storage length of a mangled name.
1422 Returns -1 on error.
1423 ****************************************************************************/
1425 int name_len(unsigned char *s1, size_t buf_len)
1427 /* NOTE: this argument _must_ be unsigned */
1428 unsigned char *s = (unsigned char *)s1;
1429 int len = 0;
1431 if (buf_len < 1) {
1432 return -1;
1434 /* If the two high bits of the byte are set, return 2. */
1435 if (0xC0 == (*s & 0xC0)) {
1436 if (buf_len < 2) {
1437 return -1;
1439 return(2);
1442 /* Add up the length bytes. */
1443 for (len = 1; (*s); s += (*s) + 1) {
1444 len += *s + 1;
1445 if (len > buf_len) {
1446 return -1;
1450 return(len);
1453 /*******************************************************************
1454 Setup the word count and byte count for a client smb message.
1455 ********************************************************************/
1457 int cli_set_message(char *buf,int num_words,int num_bytes,bool zero)
1459 if (zero && (num_words || num_bytes)) {
1460 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
1462 SCVAL(buf,smb_wct,num_words);
1463 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
1464 smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
1465 return (smb_size + num_words*2 + num_bytes);