libnmb: Move "read_packet" to nmbd
[Samba.git] / source3 / libsmb / nmblib.c
blobbac43400b3a53d8a037bb249e423f709d11cc1f4
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) {
72 return;
75 for (i = 0; i < res->rdlength; i+= MAX_NETBIOSNAME_LEN) {
76 DEBUGADD(4, (" %s %3x char ", hdr, i));
78 for (j = 0; j < MAX_NETBIOSNAME_LEN; j++) {
79 unsigned char x = res->rdata[i+j];
80 if (x < 32 || x > 127)
81 x = '.';
83 if (i+j >= res->rdlength)
84 break;
85 DEBUGADD(4, ("%c", x));
88 DEBUGADD(4, (" hex "));
90 for (j = 0; j < MAX_NETBIOSNAME_LEN; j++) {
91 if (i+j >= res->rdlength)
92 break;
93 DEBUGADD(4, ("%02X", (unsigned char)res->rdata[i+j]));
96 DEBUGADD(4, ("\n"));
100 /****************************************************************************
101 Process a nmb packet.
102 ****************************************************************************/
104 void debug_nmb_packet(struct packet_struct *p)
106 struct nmb_packet *nmb = &p->packet.nmb;
108 if( DEBUGLVL( 4 ) ) {
109 dbgtext( "nmb packet from %s(%d) header: id=%d "
110 "opcode=%s(%d) response=%s\n",
111 inet_ntoa(p->ip), p->port,
112 nmb->header.name_trn_id,
113 lookup_opcode_name(nmb->header.opcode),
114 nmb->header.opcode,
115 BOOLSTR(nmb->header.response) );
116 dbgtext( " header: flags: bcast=%s rec_avail=%s "
117 "rec_des=%s trunc=%s auth=%s\n",
118 BOOLSTR(nmb->header.nm_flags.bcast),
119 BOOLSTR(nmb->header.nm_flags.recursion_available),
120 BOOLSTR(nmb->header.nm_flags.recursion_desired),
121 BOOLSTR(nmb->header.nm_flags.trunc),
122 BOOLSTR(nmb->header.nm_flags.authoritative) );
123 dbgtext( " header: rcode=%d qdcount=%d ancount=%d "
124 "nscount=%d arcount=%d\n",
125 nmb->header.rcode,
126 nmb->header.qdcount,
127 nmb->header.ancount,
128 nmb->header.nscount,
129 nmb->header.arcount );
132 if (nmb->header.qdcount) {
133 DEBUGADD( 4, ( " question: q_name=%s q_type=%d q_class=%d\n",
134 nmb_namestr(&nmb->question.question_name),
135 nmb->question.question_type,
136 nmb->question.question_class) );
139 if (nmb->answers && nmb->header.ancount) {
140 debug_nmb_res_rec(nmb->answers,"answers");
142 if (nmb->nsrecs && nmb->header.nscount) {
143 debug_nmb_res_rec(nmb->nsrecs,"nsrecs");
145 if (nmb->additional && nmb->header.arcount) {
146 debug_nmb_res_rec(nmb->additional,"additional");
150 /*******************************************************************
151 Handle "compressed" name pointers.
152 ******************************************************************/
154 static bool handle_name_ptrs(unsigned char *ubuf,int *offset,int length,
155 bool *got_pointer,int *ret)
157 int loop_count=0;
159 while ((ubuf[*offset] & 0xC0) == 0xC0) {
160 if (!*got_pointer)
161 (*ret) += 2;
162 (*got_pointer)=True;
163 (*offset) = ((ubuf[*offset] & ~0xC0)<<8) | ubuf[(*offset)+1];
164 if (loop_count++ == 10 ||
165 (*offset) < 0 || (*offset)>(length-2)) {
166 return False;
169 return True;
172 /*******************************************************************
173 Parse a nmb name from "compressed" format to something readable
174 return the space taken by the name, or 0 if the name is invalid
175 ******************************************************************/
177 static int parse_nmb_name(char *inbuf,int ofs,int length, struct nmb_name *name)
179 int m,n=0;
180 unsigned char *ubuf = (unsigned char *)inbuf;
181 int ret = 0;
182 bool got_pointer=False;
183 int loop_count=0;
184 int offset = ofs;
186 if (length - offset < 2)
187 return(0);
189 /* handle initial name pointers */
190 if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret))
191 return(0);
193 m = ubuf[offset];
195 if (!m)
196 return(0);
197 if ((m & 0xC0) || offset+m+2 > length)
198 return(0);
200 memset((char *)name,'\0',sizeof(*name));
202 /* the "compressed" part */
203 if (!got_pointer)
204 ret += m + 2;
205 offset++;
206 while (m > 0) {
207 unsigned char c1,c2;
208 c1 = ubuf[offset++]-'A';
209 c2 = ubuf[offset++]-'A';
210 if ((c1 & 0xF0) || (c2 & 0xF0) || (n > sizeof(name->name)-1))
211 return(0);
212 name->name[n++] = (c1<<4) | c2;
213 m -= 2;
215 name->name[n] = 0;
217 if (n==MAX_NETBIOSNAME_LEN) {
218 /* parse out the name type, its always
219 * in the 16th byte of the name */
220 name->name_type = ((unsigned char)name->name[15]) & 0xff;
222 /* remove trailing spaces */
223 name->name[15] = 0;
224 n = 14;
225 while (n && name->name[n]==' ')
226 name->name[n--] = 0;
229 /* now the domain parts (if any) */
230 n = 0;
231 while (ubuf[offset]) {
232 /* we can have pointers within the domain part as well */
233 if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret))
234 return(0);
236 m = ubuf[offset];
238 * Don't allow null domain parts.
240 if (!m)
241 return(0);
242 if (!got_pointer)
243 ret += m+1;
244 if (n)
245 name->scope[n++] = '.';
246 if (m+2+offset>length || n+m+1>sizeof(name->scope))
247 return(0);
248 offset++;
249 while (m--)
250 name->scope[n++] = (char)ubuf[offset++];
253 * Watch for malicious loops.
255 if (loop_count++ == 10)
256 return 0;
258 name->scope[n++] = 0;
260 return(ret);
263 /****************************************************************************
264 Put a netbios name, padding(s) and a name type into a 16 character buffer.
265 name is already in DOS charset.
266 [15 bytes name + padding][1 byte name type].
267 ****************************************************************************/
269 void put_name(char *dest, const char *name, int pad, unsigned int name_type)
271 size_t len = strlen(name);
273 memcpy(dest, name, (len < MAX_NETBIOSNAME_LEN) ?
274 len : MAX_NETBIOSNAME_LEN - 1);
275 if (len < MAX_NETBIOSNAME_LEN - 1) {
276 memset(dest + len, pad, MAX_NETBIOSNAME_LEN - 1 - len);
278 dest[MAX_NETBIOSNAME_LEN - 1] = name_type;
281 /*******************************************************************
282 Put a compressed nmb name into a buffer. Return the length of the
283 compressed name.
285 Compressed names are really weird. The "compression" doubles the
286 size. The idea is that it also means that compressed names conform
287 to the doman name system. See RFC1002.
289 If buf == NULL this is a length calculation.
290 ******************************************************************/
292 static int put_nmb_name(char *buf, size_t buflen, int offset,struct nmb_name *name)
294 int ret,m;
295 nstring buf1;
296 char *p;
298 if (strcmp(name->name,"*") == 0) {
299 /* special case for wildcard name */
300 put_name(buf1, "*", '\0', name->name_type);
301 } else {
302 put_name(buf1, name->name, ' ', name->name_type);
305 if (buf) {
306 if (offset >= buflen) {
307 return 0;
309 buf[offset] = 0x20;
312 ret = 34;
314 for (m=0;m<MAX_NETBIOSNAME_LEN;m++) {
315 if (buf) {
316 if (offset+2+2*m >= buflen) {
317 return 0;
319 buf[offset+1+2*m] = 'A' + ((buf1[m]>>4)&0xF);
320 buf[offset+2+2*m] = 'A' + (buf1[m]&0xF);
323 offset += 33;
325 if (buf) {
326 if (offset >= buflen) {
327 return 0;
329 buf[offset] = 0;
332 if (name->scope[0]) {
333 /* XXXX this scope handling needs testing */
334 size_t scopenamelen = strlen(name->scope) + 1;
335 ret += scopenamelen;
336 if (buf) {
337 if (offset+1+scopenamelen >= buflen) {
338 return 0;
340 strlcpy(&buf[offset+1],name->scope,
341 buflen - (offset+1));
343 p = &buf[offset+1];
344 while ((p = strchr_m(p,'.'))) {
345 buf[offset] = PTR_DIFF(p,&buf[offset+1]);
346 offset += (buf[offset] + 1);
347 if (offset+1 >= buflen) {
348 return 0;
350 p = &buf[offset+1];
352 buf[offset] = strlen(&buf[offset+1]);
356 return ret;
359 /*******************************************************************
360 Useful for debugging messages.
361 ******************************************************************/
363 char *nmb_namestr(const struct nmb_name *n)
365 fstring name;
366 char *result;
368 pull_ascii_fstring(name, n->name);
369 if (!n->scope[0])
370 result = talloc_asprintf(talloc_tos(), "%s<%02x>", name,
371 n->name_type);
372 else
373 result = talloc_asprintf(talloc_tos(), "%s<%02x>.%s", name,
374 n->name_type, n->scope);
376 SMB_ASSERT(result != NULL);
377 return result;
380 /*******************************************************************
381 Allocate and parse some resource records.
382 ******************************************************************/
384 static bool parse_alloc_res_rec(char *inbuf,int *offset,int length,
385 struct res_rec **recs, int count)
387 int i;
389 *recs = SMB_MALLOC_ARRAY(struct res_rec, count);
390 if (!*recs)
391 return(False);
393 memset((char *)*recs,'\0',sizeof(**recs)*count);
395 for (i=0;i<count;i++) {
396 int l = parse_nmb_name(inbuf,*offset,length,
397 &(*recs)[i].rr_name);
398 (*offset) += l;
399 if (!l || (*offset)+10 > length) {
400 SAFE_FREE(*recs);
401 return(False);
403 (*recs)[i].rr_type = RSVAL(inbuf,(*offset));
404 (*recs)[i].rr_class = RSVAL(inbuf,(*offset)+2);
405 (*recs)[i].ttl = RIVAL(inbuf,(*offset)+4);
406 (*recs)[i].rdlength = RSVAL(inbuf,(*offset)+8);
407 (*offset) += 10;
408 if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) ||
409 (*offset)+(*recs)[i].rdlength > length) {
410 SAFE_FREE(*recs);
411 return(False);
413 memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength);
414 (*offset) += (*recs)[i].rdlength;
416 return(True);
419 /*******************************************************************
420 Put a resource record into a packet.
421 If buf == NULL this is a length calculation.
422 ******************************************************************/
424 static int put_res_rec(char *buf, size_t buflen, int offset,struct res_rec *recs,int count)
426 int ret=0;
427 int i;
429 for (i=0;i<count;i++) {
430 int l = put_nmb_name(buf,buflen,offset,&recs[i].rr_name);
431 offset += l;
432 ret += l;
433 if (buf) {
434 RSSVAL(buf,offset,recs[i].rr_type);
435 RSSVAL(buf,offset+2,recs[i].rr_class);
436 RSIVAL(buf,offset+4,recs[i].ttl);
437 RSSVAL(buf,offset+8,recs[i].rdlength);
438 memcpy(buf+offset+10,recs[i].rdata,recs[i].rdlength);
440 offset += 10+recs[i].rdlength;
441 ret += 10+recs[i].rdlength;
444 return ret;
447 /*******************************************************************
448 Put a compressed name pointer record into a packet.
449 If buf == NULL this is a length calculation.
450 ******************************************************************/
452 static int put_compressed_name_ptr(unsigned char *buf,
453 int offset,
454 struct res_rec *rec,
455 int ptr_offset)
457 int ret=0;
458 if (buf) {
459 buf[offset] = (0xC0 | ((ptr_offset >> 8) & 0xFF));
460 buf[offset+1] = (ptr_offset & 0xFF);
462 offset += 2;
463 ret += 2;
464 if (buf) {
465 RSSVAL(buf,offset,rec->rr_type);
466 RSSVAL(buf,offset+2,rec->rr_class);
467 RSIVAL(buf,offset+4,rec->ttl);
468 RSSVAL(buf,offset+8,rec->rdlength);
469 memcpy(buf+offset+10,rec->rdata,rec->rdlength);
471 offset += 10+rec->rdlength;
472 ret += 10+rec->rdlength;
474 return ret;
477 /*******************************************************************
478 Parse a dgram packet. Return False if the packet can't be parsed
479 or is invalid for some reason, True otherwise.
481 This is documented in section 4.4.1 of RFC1002.
482 ******************************************************************/
484 static bool parse_dgram(char *inbuf,int length,struct dgram_packet *dgram)
486 int offset;
487 int flags;
489 memset((char *)dgram,'\0',sizeof(*dgram));
491 if (length < 14)
492 return(False);
494 dgram->header.msg_type = CVAL(inbuf,0);
495 flags = CVAL(inbuf,1);
496 dgram->header.flags.node_type = (enum node_type)((flags>>2)&3);
497 if (flags & 1)
498 dgram->header.flags.more = True;
499 if (flags & 2)
500 dgram->header.flags.first = True;
501 dgram->header.dgm_id = RSVAL(inbuf,2);
502 putip((char *)&dgram->header.source_ip,inbuf+4);
503 dgram->header.source_port = RSVAL(inbuf,8);
504 dgram->header.dgm_length = RSVAL(inbuf,10);
505 dgram->header.packet_offset = RSVAL(inbuf,12);
507 offset = 14;
509 if (dgram->header.msg_type == 0x10 ||
510 dgram->header.msg_type == 0x11 ||
511 dgram->header.msg_type == 0x12) {
512 offset += parse_nmb_name(inbuf,offset,length,
513 &dgram->source_name);
514 offset += parse_nmb_name(inbuf,offset,length,
515 &dgram->dest_name);
518 if (offset >= length || (length-offset > sizeof(dgram->data)))
519 return(False);
521 dgram->datasize = length-offset;
522 memcpy(dgram->data,inbuf+offset,dgram->datasize);
524 /* Paranioa. Ensure the last 2 bytes in the dgram buffer are
525 zero. This should be true anyway, just enforce it for
526 paranioa sake. JRA. */
527 SMB_ASSERT(dgram->datasize <= (sizeof(dgram->data)-2));
528 memset(&dgram->data[sizeof(dgram->data)-2], '\0', 2);
530 return(True);
533 /*******************************************************************
534 Parse a nmb packet. Return False if the packet can't be parsed
535 or is invalid for some reason, True otherwise.
536 ******************************************************************/
538 static bool parse_nmb(char *inbuf,int length,struct nmb_packet *nmb)
540 int nm_flags,offset;
542 memset((char *)nmb,'\0',sizeof(*nmb));
544 if (length < 12)
545 return(False);
547 /* parse the header */
548 nmb->header.name_trn_id = RSVAL(inbuf,0);
550 DEBUG(10,("parse_nmb: packet id = %d\n", nmb->header.name_trn_id));
552 nmb->header.opcode = (CVAL(inbuf,2) >> 3) & 0xF;
553 nmb->header.response = ((CVAL(inbuf,2)>>7)&1)?True:False;
554 nm_flags = ((CVAL(inbuf,2) & 0x7) << 4) + (CVAL(inbuf,3)>>4);
555 nmb->header.nm_flags.bcast = (nm_flags&1)?True:False;
556 nmb->header.nm_flags.recursion_available = (nm_flags&8)?True:False;
557 nmb->header.nm_flags.recursion_desired = (nm_flags&0x10)?True:False;
558 nmb->header.nm_flags.trunc = (nm_flags&0x20)?True:False;
559 nmb->header.nm_flags.authoritative = (nm_flags&0x40)?True:False;
560 nmb->header.rcode = CVAL(inbuf,3) & 0xF;
561 nmb->header.qdcount = RSVAL(inbuf,4);
562 nmb->header.ancount = RSVAL(inbuf,6);
563 nmb->header.nscount = RSVAL(inbuf,8);
564 nmb->header.arcount = RSVAL(inbuf,10);
566 if (nmb->header.qdcount) {
567 offset = parse_nmb_name(inbuf,12,length,
568 &nmb->question.question_name);
569 if (!offset)
570 return(False);
572 if (length - (12+offset) < 4)
573 return(False);
574 nmb->question.question_type = RSVAL(inbuf,12+offset);
575 nmb->question.question_class = RSVAL(inbuf,12+offset+2);
577 offset += 12+4;
578 } else {
579 offset = 12;
582 /* and any resource records */
583 if (nmb->header.ancount &&
584 !parse_alloc_res_rec(inbuf,&offset,length,&nmb->answers,
585 nmb->header.ancount))
586 return(False);
588 if (nmb->header.nscount &&
589 !parse_alloc_res_rec(inbuf,&offset,length,&nmb->nsrecs,
590 nmb->header.nscount))
591 return(False);
593 if (nmb->header.arcount &&
594 !parse_alloc_res_rec(inbuf,&offset,length,
595 &nmb->additional, nmb->header.arcount))
596 return(False);
598 return(True);
601 /*******************************************************************
602 'Copy constructor' for an nmb packet.
603 ******************************************************************/
605 static struct packet_struct *copy_nmb_packet(struct packet_struct *packet)
607 struct nmb_packet *nmb;
608 struct nmb_packet *copy_nmb;
609 struct packet_struct *pkt_copy;
611 if(( pkt_copy = SMB_MALLOC_P(struct packet_struct)) == NULL) {
612 DEBUG(0,("copy_nmb_packet: malloc fail.\n"));
613 return NULL;
616 /* Structure copy of entire thing. */
618 *pkt_copy = *packet;
620 /* Ensure this copy is not locked. */
621 pkt_copy->locked = False;
622 pkt_copy->recv_fd = -1;
623 pkt_copy->send_fd = -1;
625 /* Ensure this copy has no resource records. */
626 nmb = &packet->packet.nmb;
627 copy_nmb = &pkt_copy->packet.nmb;
629 copy_nmb->answers = NULL;
630 copy_nmb->nsrecs = NULL;
631 copy_nmb->additional = NULL;
633 /* Now copy any resource records. */
635 if (nmb->answers) {
636 if((copy_nmb->answers = SMB_MALLOC_ARRAY(
637 struct res_rec,nmb->header.ancount)) == NULL)
638 goto free_and_exit;
639 memcpy((char *)copy_nmb->answers, (char *)nmb->answers,
640 nmb->header.ancount * sizeof(struct res_rec));
642 if (nmb->nsrecs) {
643 if((copy_nmb->nsrecs = SMB_MALLOC_ARRAY(
644 struct res_rec, nmb->header.nscount)) == NULL)
645 goto free_and_exit;
646 memcpy((char *)copy_nmb->nsrecs, (char *)nmb->nsrecs,
647 nmb->header.nscount * sizeof(struct res_rec));
649 if (nmb->additional) {
650 if((copy_nmb->additional = SMB_MALLOC_ARRAY(
651 struct res_rec, nmb->header.arcount)) == NULL)
652 goto free_and_exit;
653 memcpy((char *)copy_nmb->additional, (char *)nmb->additional,
654 nmb->header.arcount * sizeof(struct res_rec));
657 return pkt_copy;
659 free_and_exit:
661 SAFE_FREE(copy_nmb->answers);
662 SAFE_FREE(copy_nmb->nsrecs);
663 SAFE_FREE(copy_nmb->additional);
664 SAFE_FREE(pkt_copy);
666 DEBUG(0,("copy_nmb_packet: malloc fail in resource records.\n"));
667 return NULL;
670 /*******************************************************************
671 'Copy constructor' for a dgram packet.
672 ******************************************************************/
674 static struct packet_struct *copy_dgram_packet(struct packet_struct *packet)
676 struct packet_struct *pkt_copy;
678 if(( pkt_copy = SMB_MALLOC_P(struct packet_struct)) == NULL) {
679 DEBUG(0,("copy_dgram_packet: malloc fail.\n"));
680 return NULL;
683 /* Structure copy of entire thing. */
685 *pkt_copy = *packet;
687 /* Ensure this copy is not locked. */
688 pkt_copy->locked = False;
689 pkt_copy->recv_fd = -1;
690 pkt_copy->send_fd = -1;
692 /* There are no additional pointers in a dgram packet,
693 we are finished. */
694 return pkt_copy;
697 /*******************************************************************
698 'Copy constructor' for a generic packet.
699 ******************************************************************/
701 struct packet_struct *copy_packet(struct packet_struct *packet)
703 if(packet->packet_type == NMB_PACKET)
704 return copy_nmb_packet(packet);
705 else if (packet->packet_type == DGRAM_PACKET)
706 return copy_dgram_packet(packet);
707 return NULL;
710 /*******************************************************************
711 Free up any resources associated with an nmb packet.
712 ******************************************************************/
714 static void free_nmb_packet(struct nmb_packet *nmb)
716 SAFE_FREE(nmb->answers);
717 SAFE_FREE(nmb->nsrecs);
718 SAFE_FREE(nmb->additional);
721 /*******************************************************************
722 Free up any resources associated with a dgram packet.
723 ******************************************************************/
725 static void free_dgram_packet(struct dgram_packet *nmb)
727 /* We have nothing to do for a dgram packet. */
730 /*******************************************************************
731 Free up any resources associated with a packet.
732 ******************************************************************/
734 void free_packet(struct packet_struct *packet)
736 if (packet->locked)
737 return;
738 if (packet->packet_type == NMB_PACKET)
739 free_nmb_packet(&packet->packet.nmb);
740 else if (packet->packet_type == DGRAM_PACKET)
741 free_dgram_packet(&packet->packet.dgram);
742 ZERO_STRUCTPN(packet);
743 SAFE_FREE(packet);
746 int packet_trn_id(struct packet_struct *p)
748 int result;
749 switch (p->packet_type) {
750 case NMB_PACKET:
751 result = p->packet.nmb.header.name_trn_id;
752 break;
753 case DGRAM_PACKET:
754 result = p->packet.dgram.header.dgm_id;
755 break;
756 default:
757 result = -1;
759 return result;
762 /*******************************************************************
763 Parse a packet buffer into a packet structure.
764 ******************************************************************/
766 struct packet_struct *parse_packet(char *buf,int length,
767 enum packet_type packet_type,
768 struct in_addr ip,
769 int port)
771 struct packet_struct *p;
772 bool ok=False;
774 p = SMB_MALLOC_P(struct packet_struct);
775 if (!p)
776 return(NULL);
778 ZERO_STRUCTP(p); /* initialize for possible padding */
780 p->next = NULL;
781 p->prev = NULL;
782 p->ip = ip;
783 p->port = port;
784 p->locked = False;
785 p->timestamp = time(NULL);
786 p->packet_type = packet_type;
788 switch (packet_type) {
789 case NMB_PACKET:
790 ok = parse_nmb(buf,length,&p->packet.nmb);
791 break;
793 case DGRAM_PACKET:
794 ok = parse_dgram(buf,length,&p->packet.dgram);
795 break;
798 if (!ok) {
799 free_packet(p);
800 return NULL;
803 return p;
806 static struct packet_struct *copy_packet_talloc(
807 TALLOC_CTX *mem_ctx, const struct packet_struct *src)
809 struct packet_struct *pkt;
811 pkt = talloc_memdup(mem_ctx, src, sizeof(struct packet_struct));
812 if (pkt == NULL) {
813 return NULL;
815 pkt->locked = false;
816 pkt->recv_fd = -1;
817 pkt->send_fd = -1;
819 if (src->packet_type == NMB_PACKET) {
820 const struct nmb_packet *nsrc = &src->packet.nmb;
821 struct nmb_packet *ndst = &pkt->packet.nmb;
823 if (nsrc->answers != NULL) {
824 ndst->answers = talloc_memdup(
825 pkt, nsrc->answers,
826 sizeof(struct res_rec) * nsrc->header.ancount);
827 if (ndst->answers == NULL) {
828 goto fail;
831 if (nsrc->nsrecs != NULL) {
832 ndst->nsrecs = talloc_memdup(
833 pkt, nsrc->nsrecs,
834 sizeof(struct res_rec) * nsrc->header.nscount);
835 if (ndst->nsrecs == NULL) {
836 goto fail;
839 if (nsrc->additional != NULL) {
840 ndst->additional = talloc_memdup(
841 pkt, nsrc->additional,
842 sizeof(struct res_rec) * nsrc->header.arcount);
843 if (ndst->nsrecs == NULL) {
844 goto fail;
849 return pkt;
852 * DGRAM packets have no substructures
855 fail:
856 TALLOC_FREE(pkt);
857 return NULL;
860 struct packet_struct *parse_packet_talloc(TALLOC_CTX *mem_ctx,
861 char *buf,int length,
862 enum packet_type packet_type,
863 struct in_addr ip,
864 int port)
866 struct packet_struct *pkt, *result;
868 pkt = parse_packet(buf, length, packet_type, ip, port);
869 if (pkt == NULL) {
870 return NULL;
872 result = copy_packet_talloc(mem_ctx, pkt);
873 free_packet(pkt);
874 return result;
877 /*******************************************************************
878 Send a udp packet on a already open socket.
879 ******************************************************************/
881 static bool send_udp(int fd,char *buf,int len,struct in_addr ip,int port)
883 bool ret = False;
884 int i;
885 struct sockaddr_in sock_out;
887 /* set the address and port */
888 memset((char *)&sock_out,'\0',sizeof(sock_out));
889 putip((char *)&sock_out.sin_addr,(char *)&ip);
890 sock_out.sin_port = htons( port );
891 sock_out.sin_family = AF_INET;
893 DEBUG( 5, ( "Sending a packet of len %d to (%s) on port %d\n",
894 len, inet_ntoa(ip), port ) );
897 * Patch to fix asynch error notifications from Linux kernel.
900 for (i = 0; i < 5; i++) {
901 ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out,
902 sizeof(sock_out)) >= 0);
903 if (ret || errno != ECONNREFUSED)
904 break;
907 if (!ret)
908 DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n",
909 inet_ntoa(ip),port,strerror(errno)));
911 return(ret);
914 /*******************************************************************
915 Build a dgram packet ready for sending.
916 If buf == NULL this is a length calculation.
917 ******************************************************************/
919 static int build_dgram(char *buf, size_t len, struct dgram_packet *dgram)
921 unsigned char *ubuf = (unsigned char *)buf;
922 int offset=0;
924 /* put in the header */
925 if (buf) {
926 ubuf[0] = dgram->header.msg_type;
927 ubuf[1] = (((int)dgram->header.flags.node_type)<<2);
928 if (dgram->header.flags.more)
929 ubuf[1] |= 1;
930 if (dgram->header.flags.first)
931 ubuf[1] |= 2;
932 RSSVAL(ubuf,2,dgram->header.dgm_id);
933 putip(ubuf+4,(char *)&dgram->header.source_ip);
934 RSSVAL(ubuf,8,dgram->header.source_port);
935 RSSVAL(ubuf,12,dgram->header.packet_offset);
938 offset = 14;
940 if (dgram->header.msg_type == 0x10 ||
941 dgram->header.msg_type == 0x11 ||
942 dgram->header.msg_type == 0x12) {
943 offset += put_nmb_name((char *)ubuf,len,offset,&dgram->source_name);
944 offset += put_nmb_name((char *)ubuf,len,offset,&dgram->dest_name);
947 if (buf) {
948 memcpy(ubuf+offset,dgram->data,dgram->datasize);
950 offset += dgram->datasize;
952 /* automatically set the dgm_length
953 * NOTE: RFC1002 says the dgm_length does *not*
954 * include the fourteen-byte header. crh
956 dgram->header.dgm_length = (offset - 14);
957 if (buf) {
958 RSSVAL(ubuf,10,dgram->header.dgm_length);
961 return offset;
964 /*******************************************************************
965 Build a nmb name
966 *******************************************************************/
968 void make_nmb_name( struct nmb_name *n, const char *name, int type)
970 fstring unix_name;
971 memset( (char *)n, '\0', sizeof(struct nmb_name) );
972 fstrcpy(unix_name, name);
973 (void)strupper_m(unix_name);
974 push_ascii(n->name, unix_name, sizeof(n->name), STR_TERMINATE);
975 n->name_type = (unsigned int)type & 0xFF;
976 push_ascii(n->scope, lp_netbios_scope(), 64, STR_TERMINATE);
979 /*******************************************************************
980 Compare two nmb names
981 ******************************************************************/
983 bool nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2)
985 return ((n1->name_type == n2->name_type) &&
986 strequal(n1->name ,n2->name ) &&
987 strequal(n1->scope,n2->scope));
990 /*******************************************************************
991 Build a nmb packet ready for sending.
992 If buf == NULL this is a length calculation.
993 ******************************************************************/
995 static int build_nmb(char *buf, size_t len, struct nmb_packet *nmb)
997 unsigned char *ubuf = (unsigned char *)buf;
998 int offset=0;
1000 if (len && len < 12) {
1001 return 0;
1004 /* put in the header */
1005 if (buf) {
1006 RSSVAL(ubuf,offset,nmb->header.name_trn_id);
1007 ubuf[offset+2] = (nmb->header.opcode & 0xF) << 3;
1008 if (nmb->header.response)
1009 ubuf[offset+2] |= (1<<7);
1010 if (nmb->header.nm_flags.authoritative &&
1011 nmb->header.response)
1012 ubuf[offset+2] |= 0x4;
1013 if (nmb->header.nm_flags.trunc)
1014 ubuf[offset+2] |= 0x2;
1015 if (nmb->header.nm_flags.recursion_desired)
1016 ubuf[offset+2] |= 0x1;
1017 if (nmb->header.nm_flags.recursion_available &&
1018 nmb->header.response)
1019 ubuf[offset+3] |= 0x80;
1020 if (nmb->header.nm_flags.bcast)
1021 ubuf[offset+3] |= 0x10;
1022 ubuf[offset+3] |= (nmb->header.rcode & 0xF);
1024 RSSVAL(ubuf,offset+4,nmb->header.qdcount);
1025 RSSVAL(ubuf,offset+6,nmb->header.ancount);
1026 RSSVAL(ubuf,offset+8,nmb->header.nscount);
1027 RSSVAL(ubuf,offset+10,nmb->header.arcount);
1030 offset += 12;
1031 if (nmb->header.qdcount) {
1032 /* XXXX this doesn't handle a qdcount of > 1 */
1033 if (len) {
1034 /* Length check. */
1035 int extra = put_nmb_name(NULL,0,offset,
1036 &nmb->question.question_name);
1037 if (offset + extra > len) {
1038 return 0;
1041 offset += put_nmb_name((char *)ubuf,len,offset,
1042 &nmb->question.question_name);
1043 if (buf) {
1044 RSSVAL(ubuf,offset,nmb->question.question_type);
1045 RSSVAL(ubuf,offset+2,nmb->question.question_class);
1047 offset += 4;
1050 if (nmb->header.ancount) {
1051 if (len) {
1052 /* Length check. */
1053 int extra = put_res_rec(NULL,0,offset,nmb->answers,
1054 nmb->header.ancount);
1055 if (offset + extra > len) {
1056 return 0;
1059 offset += put_res_rec((char *)ubuf,len,offset,nmb->answers,
1060 nmb->header.ancount);
1063 if (nmb->header.nscount) {
1064 if (len) {
1065 /* Length check. */
1066 int extra = put_res_rec(NULL,0,offset,nmb->nsrecs,
1067 nmb->header.nscount);
1068 if (offset + extra > len) {
1069 return 0;
1072 offset += put_res_rec((char *)ubuf,len,offset,nmb->nsrecs,
1073 nmb->header.nscount);
1077 * The spec says we must put compressed name pointers
1078 * in the following outgoing packets :
1079 * NAME_REGISTRATION_REQUEST, NAME_REFRESH_REQUEST,
1080 * NAME_RELEASE_REQUEST.
1083 if((nmb->header.response == False) &&
1084 ((nmb->header.opcode == NMB_NAME_REG_OPCODE) ||
1085 (nmb->header.opcode == NMB_NAME_RELEASE_OPCODE) ||
1086 (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_8) ||
1087 (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_9) ||
1088 (nmb->header.opcode == NMB_NAME_MULTIHOMED_REG_OPCODE)) &&
1089 (nmb->header.arcount == 1)) {
1091 if (len) {
1092 /* Length check. */
1093 int extra = put_compressed_name_ptr(NULL,offset,
1094 nmb->additional,12);
1095 if (offset + extra > len) {
1096 return 0;
1099 offset += put_compressed_name_ptr(ubuf,offset,
1100 nmb->additional,12);
1101 } else if (nmb->header.arcount) {
1102 if (len) {
1103 /* Length check. */
1104 int extra = put_res_rec(NULL,0,offset,nmb->additional,
1105 nmb->header.arcount);
1106 if (offset + extra > len) {
1107 return 0;
1110 offset += put_res_rec((char *)ubuf,len,offset,nmb->additional,
1111 nmb->header.arcount);
1113 return offset;
1116 /*******************************************************************
1117 Linearise a packet.
1118 ******************************************************************/
1120 int build_packet(char *buf, size_t buflen, struct packet_struct *p)
1122 int len = 0;
1124 switch (p->packet_type) {
1125 case NMB_PACKET:
1126 len = build_nmb(buf,buflen,&p->packet.nmb);
1127 break;
1129 case DGRAM_PACKET:
1130 len = build_dgram(buf,buflen,&p->packet.dgram);
1131 break;
1134 return len;
1137 /*******************************************************************
1138 Send a packet_struct.
1139 ******************************************************************/
1141 bool send_packet(struct packet_struct *p)
1143 char buf[1024];
1144 int len=0;
1146 memset(buf,'\0',sizeof(buf));
1148 len = build_packet(buf, sizeof(buf), p);
1150 if (!len)
1151 return(False);
1153 return(send_udp(p->send_fd,buf,len,p->ip,p->port));
1156 /****************************************************************************
1157 Receive a UDP/138 packet either via UDP or from the unexpected packet
1158 queue. The packet must be a reply packet and have the specified mailslot name
1159 The timeout is in milliseconds.
1160 ***************************************************************************/
1162 /****************************************************************************
1163 See if a datagram has the right mailslot name.
1164 ***************************************************************************/
1166 bool match_mailslot_name(struct packet_struct *p, const char *mailslot_name)
1168 struct dgram_packet *dgram = &p->packet.dgram;
1169 char *buf;
1171 buf = &dgram->data[0];
1172 buf -= 4;
1174 buf = smb_buf(buf);
1176 if (memcmp(buf, mailslot_name, strlen(mailslot_name)+1) == 0) {
1177 return True;
1180 return False;
1183 /****************************************************************************
1184 Return the number of bits that match between two len character buffers
1185 ***************************************************************************/
1187 int matching_len_bits(const unsigned char *p1, const unsigned char *p2, size_t len)
1189 size_t i, j;
1190 int ret = 0;
1191 for (i=0; i<len; i++) {
1192 if (p1[i] != p2[i])
1193 break;
1194 ret += 8;
1197 if (i==len)
1198 return ret;
1200 for (j=0; j<8; j++) {
1201 if ((p1[i] & (1<<(7-j))) != (p2[i] & (1<<(7-j))))
1202 break;
1203 ret++;
1206 return ret;
1209 static unsigned char sort_ip[4];
1211 /****************************************************************************
1212 Compare two query reply records.
1213 ***************************************************************************/
1215 static int name_query_comp(unsigned char *p1, unsigned char *p2)
1217 return matching_len_bits(p2+2, sort_ip, 4) -
1218 matching_len_bits(p1+2, sort_ip, 4);
1221 /****************************************************************************
1222 Sort a set of 6 byte name query response records so that the IPs that
1223 have the most leading bits in common with the specified address come first.
1224 ***************************************************************************/
1226 void sort_query_replies(char *data, int n, struct in_addr ip)
1228 if (n <= 1)
1229 return;
1231 putip(sort_ip, (char *)&ip);
1233 /* TODO:
1234 this can't use TYPESAFE_QSORT() as the types are wrong.
1235 It should be fixed to use a real type instead of char*
1237 qsort(data, n, 6, QSORT_CAST name_query_comp);
1240 /****************************************************************************
1241 Interpret the weird netbios "name" into a unix fstring. Return the name type.
1242 Returns -1 on error.
1243 ****************************************************************************/
1245 static int name_interpret(unsigned char *buf, size_t buf_len,
1246 unsigned char *in, fstring name)
1248 unsigned char *end_ptr = buf + buf_len;
1249 int ret;
1250 unsigned int len;
1251 fstring out_string;
1252 unsigned char *out = (unsigned char *)out_string;
1254 *out=0;
1256 if (in >= end_ptr) {
1257 return -1;
1259 len = (*in++) / 2;
1261 if (len<1) {
1262 return -1;
1265 while (len--) {
1266 if (&in[1] >= end_ptr) {
1267 return -1;
1269 if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
1270 *out = 0;
1271 return(0);
1273 *out = ((in[0]-'A')<<4) + (in[1]-'A');
1274 in += 2;
1275 out++;
1276 if (PTR_DIFF(out,out_string) >= sizeof(fstring)) {
1277 return -1;
1280 ret = out[-1];
1281 out[-1] = 0;
1283 pull_ascii_fstring(name, out_string);
1285 return(ret);
1288 /****************************************************************************
1289 Mangle a name into netbios format.
1290 Note: <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
1291 ****************************************************************************/
1293 char *name_mangle(TALLOC_CTX *mem_ctx, const char *In, char name_type)
1295 int i;
1296 int len;
1297 nstring buf;
1298 char *result;
1299 char *p;
1301 result = talloc_array(mem_ctx, char, 33 + strlen(lp_netbios_scope()) + 2);
1302 if (result == NULL) {
1303 return NULL;
1305 p = result;
1307 /* Safely copy the input string, In, into buf[]. */
1308 if (strcmp(In,"*") == 0)
1309 put_name(buf, "*", '\0', 0x00);
1310 else {
1311 /* We use an fstring here as mb dos names can expend x3 when
1312 going to utf8. */
1313 fstring buf_unix;
1314 nstring buf_dos;
1316 pull_ascii_fstring(buf_unix, In);
1317 if (!strupper_m(buf_unix)) {
1318 return NULL;
1321 push_ascii_nstring(buf_dos, buf_unix);
1322 put_name(buf, buf_dos, ' ', name_type);
1325 /* Place the length of the first field into the output buffer. */
1326 p[0] = 32;
1327 p++;
1329 /* Now convert the name to the rfc1001/1002 format. */
1330 for( i = 0; i < MAX_NETBIOSNAME_LEN; i++ ) {
1331 p[i*2] = ( (buf[i] >> 4) & 0x000F ) + 'A';
1332 p[(i*2)+1] = (buf[i] & 0x000F) + 'A';
1334 p += 32;
1335 p[0] = '\0';
1337 /* Add the scope string. */
1338 for( i = 0, len = 0; *(lp_netbios_scope()) != '\0'; i++, len++ ) {
1339 switch( (lp_netbios_scope())[i] ) {
1340 case '\0':
1341 p[0] = len;
1342 if( len > 0 )
1343 p[len+1] = 0;
1344 return result;
1345 case '.':
1346 p[0] = len;
1347 p += (len + 1);
1348 len = -1;
1349 break;
1350 default:
1351 p[len+1] = (lp_netbios_scope())[i];
1352 break;
1356 return result;
1359 /****************************************************************************
1360 Find a pointer to a netbios name.
1361 ****************************************************************************/
1363 static unsigned char *name_ptr(unsigned char *buf, size_t buf_len, unsigned int ofs)
1365 unsigned char c = 0;
1367 if (ofs > buf_len || buf_len < 1) {
1368 return NULL;
1371 c = *(unsigned char *)(buf+ofs);
1372 if ((c & 0xC0) == 0xC0) {
1373 uint16_t l = 0;
1375 if (ofs > buf_len - 1) {
1376 return NULL;
1378 l = RSVAL(buf, ofs) & 0x3FFF;
1379 if (l > buf_len) {
1380 return NULL;
1382 DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
1383 return(buf + l);
1384 } else {
1385 return(buf+ofs);
1389 /****************************************************************************
1390 Extract a netbios name from a buf (into a unix string) return name type.
1391 Returns -1 on error.
1392 ****************************************************************************/
1394 int name_extract(unsigned char *buf, size_t buf_len, unsigned int ofs, fstring name)
1396 unsigned char *p = name_ptr(buf,buf_len,ofs);
1398 name[0] = '\0';
1399 if (p == NULL) {
1400 return -1;
1402 return(name_interpret(buf,buf_len,p,name));
1405 /****************************************************************************
1406 Return the total storage length of a mangled name.
1407 Returns -1 on error.
1408 ****************************************************************************/
1410 int name_len(unsigned char *s1, size_t buf_len)
1412 /* NOTE: this argument _must_ be unsigned */
1413 unsigned char *s = (unsigned char *)s1;
1414 int len = 0;
1416 if (buf_len < 1) {
1417 return -1;
1419 /* If the two high bits of the byte are set, return 2. */
1420 if (0xC0 == (*s & 0xC0)) {
1421 if (buf_len < 2) {
1422 return -1;
1424 return(2);
1427 /* Add up the length bytes. */
1428 for (len = 1; (*s); s += (*s) + 1) {
1429 len += *s + 1;
1430 if (len > buf_len) {
1431 return -1;
1435 return(len);