packet_struct is used in several places as raw memory
[Samba.git] / source / libsmb / nmblib.c
blob15a9a93ff29c37306e1ba9c0becfe929115ea085
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"
24 int num_good_sends = 0;
25 int num_good_receives = 0;
27 static const struct opcode_names {
28 const char *nmb_opcode_name;
29 int opcode;
30 } nmb_header_opcode_names[] = {
31 {"Query", 0 },
32 {"Registration", 5 },
33 {"Release", 6 },
34 {"WACK", 7 },
35 {"Refresh", 8 },
36 {"Refresh(altcode)", 9 },
37 {"Multi-homed Registration", 15 },
38 {0, -1 }
41 /****************************************************************************
42 Lookup a nmb opcode name.
43 ****************************************************************************/
45 static const char *lookup_opcode_name( int opcode )
47 const struct opcode_names *op_namep;
48 int i;
50 for(i = 0; nmb_header_opcode_names[i].nmb_opcode_name != 0; i++) {
51 op_namep = &nmb_header_opcode_names[i];
52 if(opcode == op_namep->opcode)
53 return op_namep->nmb_opcode_name;
55 return "<unknown opcode>";
58 /****************************************************************************
59 Print out a res_rec structure.
60 ****************************************************************************/
62 static void debug_nmb_res_rec(struct res_rec *res, const char *hdr)
64 int i, j;
66 DEBUGADD( 4, ( " %s: nmb_name=%s rr_type=%d rr_class=%d ttl=%d\n",
67 hdr,
68 nmb_namestr(&res->rr_name),
69 res->rr_type,
70 res->rr_class,
71 res->ttl ) );
73 if( res->rdlength == 0 || res->rdata == NULL )
74 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 (*offset) = ((ubuf[*offset] & ~0xC0)<<8) | ubuf[(*offset)+1];
165 if (loop_count++ == 10 ||
166 (*offset) < 0 || (*offset)>(length-2)) {
167 return False;
170 return True;
173 /*******************************************************************
174 Parse a nmb name from "compressed" format to something readable
175 return the space taken by the name, or 0 if the name is invalid
176 ******************************************************************/
178 static int parse_nmb_name(char *inbuf,int ofs,int length, struct nmb_name *name)
180 int m,n=0;
181 unsigned char *ubuf = (unsigned char *)inbuf;
182 int ret = 0;
183 bool got_pointer=False;
184 int loop_count=0;
185 int offset = ofs;
187 if (length - offset < 2)
188 return(0);
190 /* handle initial name pointers */
191 if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret))
192 return(0);
194 m = ubuf[offset];
196 if (!m)
197 return(0);
198 if ((m & 0xC0) || offset+m+2 > length)
199 return(0);
201 memset((char *)name,'\0',sizeof(*name));
203 /* the "compressed" part */
204 if (!got_pointer)
205 ret += m + 2;
206 offset++;
207 while (m > 0) {
208 unsigned char c1,c2;
209 c1 = ubuf[offset++]-'A';
210 c2 = ubuf[offset++]-'A';
211 if ((c1 & 0xF0) || (c2 & 0xF0) || (n > sizeof(name->name)-1))
212 return(0);
213 name->name[n++] = (c1<<4) | c2;
214 m -= 2;
216 name->name[n] = 0;
218 if (n==MAX_NETBIOSNAME_LEN) {
219 /* parse out the name type, its always
220 * in the 16th byte of the name */
221 name->name_type = ((unsigned char)name->name[15]) & 0xff;
223 /* remove trailing spaces */
224 name->name[15] = 0;
225 n = 14;
226 while (n && name->name[n]==' ')
227 name->name[n--] = 0;
230 /* now the domain parts (if any) */
231 n = 0;
232 while (ubuf[offset]) {
233 /* we can have pointers within the domain part as well */
234 if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret))
235 return(0);
237 m = ubuf[offset];
239 * Don't allow null domain parts.
241 if (!m)
242 return(0);
243 if (!got_pointer)
244 ret += m+1;
245 if (n)
246 name->scope[n++] = '.';
247 if (m+2+offset>length || n+m+1>sizeof(name->scope))
248 return(0);
249 offset++;
250 while (m--)
251 name->scope[n++] = (char)ubuf[offset++];
254 * Watch for malicious loops.
256 if (loop_count++ == 10)
257 return 0;
259 name->scope[n++] = 0;
261 return(ret);
264 /****************************************************************************
265 Put a netbios name, padding(s) and a name type into a 16 character buffer.
266 name is already in DOS charset.
267 [15 bytes name + padding][1 byte name type].
268 ****************************************************************************/
270 void put_name(char *dest, const char *name, int pad, unsigned int name_type)
272 size_t len = strlen(name);
274 memcpy(dest, name, (len < MAX_NETBIOSNAME_LEN) ?
275 len : MAX_NETBIOSNAME_LEN - 1);
276 if (len < MAX_NETBIOSNAME_LEN - 1) {
277 memset(dest + len, pad, MAX_NETBIOSNAME_LEN - 1 - len);
279 dest[MAX_NETBIOSNAME_LEN - 1] = name_type;
282 /*******************************************************************
283 Put a compressed nmb name into a buffer. Return the length of the
284 compressed name.
286 Compressed names are really weird. The "compression" doubles the
287 size. The idea is that it also means that compressed names conform
288 to the doman name system. See RFC1002.
290 If buf == NULL this is a length calculation.
291 ******************************************************************/
293 static int put_nmb_name(char *buf,int offset,struct nmb_name *name)
295 int ret,m;
296 nstring buf1;
297 char *p;
299 if (strcmp(name->name,"*") == 0) {
300 /* special case for wildcard name */
301 put_name(buf1, "*", '\0', name->name_type);
302 } else {
303 put_name(buf1, name->name, ' ', name->name_type);
306 if (buf) {
307 buf[offset] = 0x20;
310 ret = 34;
312 for (m=0;m<MAX_NETBIOSNAME_LEN;m++) {
313 if (buf) {
314 buf[offset+1+2*m] = 'A' + ((buf1[m]>>4)&0xF);
315 buf[offset+2+2*m] = 'A' + (buf1[m]&0xF);
318 offset += 33;
320 if (buf) {
321 buf[offset] = 0;
324 if (name->scope[0]) {
325 /* XXXX this scope handling needs testing */
326 ret += strlen(name->scope) + 1;
327 if (buf) {
328 safe_strcpy(&buf[offset+1],name->scope,
329 sizeof(name->scope));
331 p = &buf[offset+1];
332 while ((p = strchr_m(p,'.'))) {
333 buf[offset] = PTR_DIFF(p,&buf[offset+1]);
334 offset += (buf[offset] + 1);
335 p = &buf[offset+1];
337 buf[offset] = strlen(&buf[offset+1]);
341 return ret;
344 /*******************************************************************
345 Useful for debugging messages.
346 ******************************************************************/
348 char *nmb_namestr(const struct nmb_name *n)
350 fstring name;
351 char *result;
353 pull_ascii_fstring(name, n->name);
354 if (!n->scope[0])
355 result = talloc_asprintf(talloc_tos(), "%s<%02x>", name,
356 n->name_type);
357 else
358 result = talloc_asprintf(talloc_tos(), "%s<%02x>.%s", name,
359 n->name_type, n->scope);
361 SMB_ASSERT(result != NULL);
362 return result;
365 /*******************************************************************
366 Allocate and parse some resource records.
367 ******************************************************************/
369 static bool parse_alloc_res_rec(char *inbuf,int *offset,int length,
370 struct res_rec **recs, int count)
372 int i;
374 *recs = SMB_MALLOC_ARRAY(struct res_rec, count);
375 if (!*recs)
376 return(False);
378 memset((char *)*recs,'\0',sizeof(**recs)*count);
380 for (i=0;i<count;i++) {
381 int l = parse_nmb_name(inbuf,*offset,length,
382 &(*recs)[i].rr_name);
383 (*offset) += l;
384 if (!l || (*offset)+10 > length) {
385 SAFE_FREE(*recs);
386 return(False);
388 (*recs)[i].rr_type = RSVAL(inbuf,(*offset));
389 (*recs)[i].rr_class = RSVAL(inbuf,(*offset)+2);
390 (*recs)[i].ttl = RIVAL(inbuf,(*offset)+4);
391 (*recs)[i].rdlength = RSVAL(inbuf,(*offset)+8);
392 (*offset) += 10;
393 if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) ||
394 (*offset)+(*recs)[i].rdlength > length) {
395 SAFE_FREE(*recs);
396 return(False);
398 memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength);
399 (*offset) += (*recs)[i].rdlength;
401 return(True);
404 /*******************************************************************
405 Put a resource record into a packet.
406 If buf == NULL this is a length calculation.
407 ******************************************************************/
409 static int put_res_rec(char *buf,int offset,struct res_rec *recs,int count)
411 int ret=0;
412 int i;
414 for (i=0;i<count;i++) {
415 int l = put_nmb_name(buf,offset,&recs[i].rr_name);
416 offset += l;
417 ret += l;
418 if (buf) {
419 RSSVAL(buf,offset,recs[i].rr_type);
420 RSSVAL(buf,offset+2,recs[i].rr_class);
421 RSIVAL(buf,offset+4,recs[i].ttl);
422 RSSVAL(buf,offset+8,recs[i].rdlength);
423 memcpy(buf+offset+10,recs[i].rdata,recs[i].rdlength);
425 offset += 10+recs[i].rdlength;
426 ret += 10+recs[i].rdlength;
429 return ret;
432 /*******************************************************************
433 Put a compressed name pointer record into a packet.
434 If buf == NULL this is a length calculation.
435 ******************************************************************/
437 static int put_compressed_name_ptr(unsigned char *buf,
438 int offset,
439 struct res_rec *rec,
440 int ptr_offset)
442 int ret=0;
443 if (buf) {
444 buf[offset] = (0xC0 | ((ptr_offset >> 8) & 0xFF));
445 buf[offset+1] = (ptr_offset & 0xFF);
447 offset += 2;
448 ret += 2;
449 if (buf) {
450 RSSVAL(buf,offset,rec->rr_type);
451 RSSVAL(buf,offset+2,rec->rr_class);
452 RSIVAL(buf,offset+4,rec->ttl);
453 RSSVAL(buf,offset+8,rec->rdlength);
454 memcpy(buf+offset+10,rec->rdata,rec->rdlength);
456 offset += 10+rec->rdlength;
457 ret += 10+rec->rdlength;
459 return ret;
462 /*******************************************************************
463 Parse a dgram packet. Return False if the packet can't be parsed
464 or is invalid for some reason, True otherwise.
466 This is documented in section 4.4.1 of RFC1002.
467 ******************************************************************/
469 static bool parse_dgram(char *inbuf,int length,struct dgram_packet *dgram)
471 int offset;
472 int flags;
474 memset((char *)dgram,'\0',sizeof(*dgram));
476 if (length < 14)
477 return(False);
479 dgram->header.msg_type = CVAL(inbuf,0);
480 flags = CVAL(inbuf,1);
481 dgram->header.flags.node_type = (enum node_type)((flags>>2)&3);
482 if (flags & 1)
483 dgram->header.flags.more = True;
484 if (flags & 2)
485 dgram->header.flags.first = True;
486 dgram->header.dgm_id = RSVAL(inbuf,2);
487 putip((char *)&dgram->header.source_ip,inbuf+4);
488 dgram->header.source_port = RSVAL(inbuf,8);
489 dgram->header.dgm_length = RSVAL(inbuf,10);
490 dgram->header.packet_offset = RSVAL(inbuf,12);
492 offset = 14;
494 if (dgram->header.msg_type == 0x10 ||
495 dgram->header.msg_type == 0x11 ||
496 dgram->header.msg_type == 0x12) {
497 offset += parse_nmb_name(inbuf,offset,length,
498 &dgram->source_name);
499 offset += parse_nmb_name(inbuf,offset,length,
500 &dgram->dest_name);
503 if (offset >= length || (length-offset > sizeof(dgram->data)))
504 return(False);
506 dgram->datasize = length-offset;
507 memcpy(dgram->data,inbuf+offset,dgram->datasize);
509 /* Paranioa. Ensure the last 2 bytes in the dgram buffer are
510 zero. This should be true anyway, just enforce it for
511 paranioa sake. JRA. */
512 SMB_ASSERT(dgram->datasize <= (sizeof(dgram->data)-2));
513 memset(&dgram->data[sizeof(dgram->data)-2], '\0', 2);
515 return(True);
518 /*******************************************************************
519 Parse a nmb packet. Return False if the packet can't be parsed
520 or is invalid for some reason, True otherwise.
521 ******************************************************************/
523 static bool parse_nmb(char *inbuf,int length,struct nmb_packet *nmb)
525 int nm_flags,offset;
527 memset((char *)nmb,'\0',sizeof(*nmb));
529 if (length < 12)
530 return(False);
532 /* parse the header */
533 nmb->header.name_trn_id = RSVAL(inbuf,0);
535 DEBUG(10,("parse_nmb: packet id = %d\n", nmb->header.name_trn_id));
537 nmb->header.opcode = (CVAL(inbuf,2) >> 3) & 0xF;
538 nmb->header.response = ((CVAL(inbuf,2)>>7)&1)?True:False;
539 nm_flags = ((CVAL(inbuf,2) & 0x7) << 4) + (CVAL(inbuf,3)>>4);
540 nmb->header.nm_flags.bcast = (nm_flags&1)?True:False;
541 nmb->header.nm_flags.recursion_available = (nm_flags&8)?True:False;
542 nmb->header.nm_flags.recursion_desired = (nm_flags&0x10)?True:False;
543 nmb->header.nm_flags.trunc = (nm_flags&0x20)?True:False;
544 nmb->header.nm_flags.authoritative = (nm_flags&0x40)?True:False;
545 nmb->header.rcode = CVAL(inbuf,3) & 0xF;
546 nmb->header.qdcount = RSVAL(inbuf,4);
547 nmb->header.ancount = RSVAL(inbuf,6);
548 nmb->header.nscount = RSVAL(inbuf,8);
549 nmb->header.arcount = RSVAL(inbuf,10);
551 if (nmb->header.qdcount) {
552 offset = parse_nmb_name(inbuf,12,length,
553 &nmb->question.question_name);
554 if (!offset)
555 return(False);
557 if (length - (12+offset) < 4)
558 return(False);
559 nmb->question.question_type = RSVAL(inbuf,12+offset);
560 nmb->question.question_class = RSVAL(inbuf,12+offset+2);
562 offset += 12+4;
563 } else {
564 offset = 12;
567 /* and any resource records */
568 if (nmb->header.ancount &&
569 !parse_alloc_res_rec(inbuf,&offset,length,&nmb->answers,
570 nmb->header.ancount))
571 return(False);
573 if (nmb->header.nscount &&
574 !parse_alloc_res_rec(inbuf,&offset,length,&nmb->nsrecs,
575 nmb->header.nscount))
576 return(False);
578 if (nmb->header.arcount &&
579 !parse_alloc_res_rec(inbuf,&offset,length,
580 &nmb->additional, nmb->header.arcount))
581 return(False);
583 return(True);
586 /*******************************************************************
587 'Copy constructor' for an nmb packet.
588 ******************************************************************/
590 static struct packet_struct *copy_nmb_packet(struct packet_struct *packet)
592 struct nmb_packet *nmb;
593 struct nmb_packet *copy_nmb;
594 struct packet_struct *pkt_copy;
596 if(( pkt_copy = SMB_MALLOC_P(struct packet_struct)) == NULL) {
597 DEBUG(0,("copy_nmb_packet: malloc fail.\n"));
598 return NULL;
601 /* Structure copy of entire thing. */
603 *pkt_copy = *packet;
605 /* Ensure this copy is not locked. */
606 pkt_copy->locked = False;
608 /* Ensure this copy has no resource records. */
609 nmb = &packet->packet.nmb;
610 copy_nmb = &pkt_copy->packet.nmb;
612 copy_nmb->answers = NULL;
613 copy_nmb->nsrecs = NULL;
614 copy_nmb->additional = NULL;
616 /* Now copy any resource records. */
618 if (nmb->answers) {
619 if((copy_nmb->answers = SMB_MALLOC_ARRAY(
620 struct res_rec,nmb->header.ancount)) == NULL)
621 goto free_and_exit;
622 memcpy((char *)copy_nmb->answers, (char *)nmb->answers,
623 nmb->header.ancount * sizeof(struct res_rec));
625 if (nmb->nsrecs) {
626 if((copy_nmb->nsrecs = SMB_MALLOC_ARRAY(
627 struct res_rec, nmb->header.nscount)) == NULL)
628 goto free_and_exit;
629 memcpy((char *)copy_nmb->nsrecs, (char *)nmb->nsrecs,
630 nmb->header.nscount * sizeof(struct res_rec));
632 if (nmb->additional) {
633 if((copy_nmb->additional = SMB_MALLOC_ARRAY(
634 struct res_rec, nmb->header.arcount)) == NULL)
635 goto free_and_exit;
636 memcpy((char *)copy_nmb->additional, (char *)nmb->additional,
637 nmb->header.arcount * sizeof(struct res_rec));
640 return pkt_copy;
642 free_and_exit:
644 SAFE_FREE(copy_nmb->answers);
645 SAFE_FREE(copy_nmb->nsrecs);
646 SAFE_FREE(copy_nmb->additional);
647 SAFE_FREE(pkt_copy);
649 DEBUG(0,("copy_nmb_packet: malloc fail in resource records.\n"));
650 return NULL;
653 /*******************************************************************
654 'Copy constructor' for a dgram packet.
655 ******************************************************************/
657 static struct packet_struct *copy_dgram_packet(struct packet_struct *packet)
659 struct packet_struct *pkt_copy;
661 if(( pkt_copy = SMB_MALLOC_P(struct packet_struct)) == NULL) {
662 DEBUG(0,("copy_dgram_packet: malloc fail.\n"));
663 return NULL;
666 /* Structure copy of entire thing. */
668 *pkt_copy = *packet;
670 /* Ensure this copy is not locked. */
671 pkt_copy->locked = False;
673 /* There are no additional pointers in a dgram packet,
674 we are finished. */
675 return pkt_copy;
678 /*******************************************************************
679 'Copy constructor' for a generic packet.
680 ******************************************************************/
682 struct packet_struct *copy_packet(struct packet_struct *packet)
684 if(packet->packet_type == NMB_PACKET)
685 return copy_nmb_packet(packet);
686 else if (packet->packet_type == DGRAM_PACKET)
687 return copy_dgram_packet(packet);
688 return NULL;
691 /*******************************************************************
692 Free up any resources associated with an nmb packet.
693 ******************************************************************/
695 static void free_nmb_packet(struct nmb_packet *nmb)
697 SAFE_FREE(nmb->answers);
698 SAFE_FREE(nmb->nsrecs);
699 SAFE_FREE(nmb->additional);
702 /*******************************************************************
703 Free up any resources associated with a dgram packet.
704 ******************************************************************/
706 static void free_dgram_packet(struct dgram_packet *nmb)
708 /* We have nothing to do for a dgram packet. */
711 /*******************************************************************
712 Free up any resources associated with a packet.
713 ******************************************************************/
715 void free_packet(struct packet_struct *packet)
717 if (packet->locked)
718 return;
719 if (packet->packet_type == NMB_PACKET)
720 free_nmb_packet(&packet->packet.nmb);
721 else if (packet->packet_type == DGRAM_PACKET)
722 free_dgram_packet(&packet->packet.dgram);
723 ZERO_STRUCTPN(packet);
724 SAFE_FREE(packet);
727 /*******************************************************************
728 Parse a packet buffer into a packet structure.
729 ******************************************************************/
731 struct packet_struct *parse_packet(char *buf,int length,
732 enum packet_type packet_type,
733 struct in_addr ip,
734 int port)
736 struct packet_struct *p;
737 bool ok=False;
739 p = SMB_MALLOC_P(struct packet_struct);
740 if (!p)
741 return(NULL);
743 ZERO_STRUCTP(p); /* initialize for possible padding */
745 p->next = NULL;
746 p->prev = NULL;
747 p->ip = ip;
748 p->port = port;
749 p->locked = False;
750 p->timestamp = time(NULL);
751 p->packet_type = packet_type;
753 switch (packet_type) {
754 case NMB_PACKET:
755 ok = parse_nmb(buf,length,&p->packet.nmb);
756 break;
758 case DGRAM_PACKET:
759 ok = parse_dgram(buf,length,&p->packet.dgram);
760 break;
763 if (!ok) {
764 free_packet(p);
765 return NULL;
768 return p;
771 /*******************************************************************
772 Read a packet from a socket and parse it, returning a packet ready
773 to be used or put on the queue. This assumes a UDP socket.
774 ******************************************************************/
776 struct packet_struct *read_packet(int fd,enum packet_type packet_type)
778 struct packet_struct *packet;
779 struct sockaddr_storage sa;
780 struct sockaddr_in *si = (struct sockaddr_in *)&sa;
781 char buf[MAX_DGRAM_SIZE];
782 int length;
784 length = read_udp_v4_socket(fd,buf,sizeof(buf),&sa);
785 if (length < MIN_DGRAM_SIZE || sa.ss_family != AF_INET) {
786 return NULL;
789 packet = parse_packet(buf,
790 length,
791 packet_type,
792 si->sin_addr,
793 ntohs(si->sin_port));
794 if (!packet)
795 return NULL;
797 packet->fd = fd;
799 num_good_receives++;
801 DEBUG(5,("Received a packet of len %d from (%s) port %d\n",
802 length, inet_ntoa(packet->ip), packet->port ) );
804 return(packet);
807 /*******************************************************************
808 Send a udp packet on a already open socket.
809 ******************************************************************/
811 static bool send_udp(int fd,char *buf,int len,struct in_addr ip,int port)
813 bool ret = False;
814 int i;
815 struct sockaddr_in sock_out;
817 /* set the address and port */
818 memset((char *)&sock_out,'\0',sizeof(sock_out));
819 putip((char *)&sock_out.sin_addr,(char *)&ip);
820 sock_out.sin_port = htons( port );
821 sock_out.sin_family = AF_INET;
823 DEBUG( 5, ( "Sending a packet of len %d to (%s) on port %d\n",
824 len, inet_ntoa(ip), port ) );
827 * Patch to fix asynch error notifications from Linux kernel.
830 for (i = 0; i < 5; i++) {
831 ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out,
832 sizeof(sock_out)) >= 0);
833 if (ret || errno != ECONNREFUSED)
834 break;
837 if (!ret)
838 DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n",
839 inet_ntoa(ip),port,strerror(errno)));
841 if (ret)
842 num_good_sends++;
844 return(ret);
847 /*******************************************************************
848 Build a dgram packet ready for sending.
849 If buf == NULL this is a length calculation.
850 ******************************************************************/
852 static int build_dgram(char *buf, size_t len, struct packet_struct *p)
854 struct dgram_packet *dgram = &p->packet.dgram;
855 unsigned char *ubuf = (unsigned char *)buf;
856 int offset=0;
858 /* put in the header */
859 if (buf) {
860 ubuf[0] = dgram->header.msg_type;
861 ubuf[1] = (((int)dgram->header.flags.node_type)<<2);
862 if (dgram->header.flags.more)
863 ubuf[1] |= 1;
864 if (dgram->header.flags.first)
865 ubuf[1] |= 2;
866 RSSVAL(ubuf,2,dgram->header.dgm_id);
867 putip(ubuf+4,(char *)&dgram->header.source_ip);
868 RSSVAL(ubuf,8,dgram->header.source_port);
869 RSSVAL(ubuf,12,dgram->header.packet_offset);
872 offset = 14;
874 if (dgram->header.msg_type == 0x10 ||
875 dgram->header.msg_type == 0x11 ||
876 dgram->header.msg_type == 0x12) {
877 offset += put_nmb_name((char *)ubuf,offset,&dgram->source_name);
878 offset += put_nmb_name((char *)ubuf,offset,&dgram->dest_name);
881 if (buf) {
882 memcpy(ubuf+offset,dgram->data,dgram->datasize);
884 offset += dgram->datasize;
886 /* automatically set the dgm_length
887 * NOTE: RFC1002 says the dgm_length does *not*
888 * include the fourteen-byte header. crh
890 dgram->header.dgm_length = (offset - 14);
891 if (buf) {
892 RSSVAL(ubuf,10,dgram->header.dgm_length);
895 return offset;
898 /*******************************************************************
899 Build a nmb name
900 *******************************************************************/
902 void make_nmb_name( struct nmb_name *n, const char *name, int type)
904 fstring unix_name;
905 memset( (char *)n, '\0', sizeof(struct nmb_name) );
906 fstrcpy(unix_name, name);
907 strupper_m(unix_name);
908 push_ascii(n->name, unix_name, sizeof(n->name), STR_TERMINATE);
909 n->name_type = (unsigned int)type & 0xFF;
910 push_ascii(n->scope, global_scope(), 64, STR_TERMINATE);
913 /*******************************************************************
914 Compare two nmb names
915 ******************************************************************/
917 bool nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2)
919 return ((n1->name_type == n2->name_type) &&
920 strequal(n1->name ,n2->name ) &&
921 strequal(n1->scope,n2->scope));
924 /*******************************************************************
925 Build a nmb packet ready for sending.
926 If buf == NULL this is a length calculation.
927 ******************************************************************/
929 static int build_nmb(char *buf, size_t len, struct packet_struct *p)
931 struct nmb_packet *nmb = &p->packet.nmb;
932 unsigned char *ubuf = (unsigned char *)buf;
933 int offset=0;
935 if (len && len < 12) {
936 return 0;
939 /* put in the header */
940 if (buf) {
941 RSSVAL(ubuf,offset,nmb->header.name_trn_id);
942 ubuf[offset+2] = (nmb->header.opcode & 0xF) << 3;
943 if (nmb->header.response)
944 ubuf[offset+2] |= (1<<7);
945 if (nmb->header.nm_flags.authoritative &&
946 nmb->header.response)
947 ubuf[offset+2] |= 0x4;
948 if (nmb->header.nm_flags.trunc)
949 ubuf[offset+2] |= 0x2;
950 if (nmb->header.nm_flags.recursion_desired)
951 ubuf[offset+2] |= 0x1;
952 if (nmb->header.nm_flags.recursion_available &&
953 nmb->header.response)
954 ubuf[offset+3] |= 0x80;
955 if (nmb->header.nm_flags.bcast)
956 ubuf[offset+3] |= 0x10;
957 ubuf[offset+3] |= (nmb->header.rcode & 0xF);
959 RSSVAL(ubuf,offset+4,nmb->header.qdcount);
960 RSSVAL(ubuf,offset+6,nmb->header.ancount);
961 RSSVAL(ubuf,offset+8,nmb->header.nscount);
962 RSSVAL(ubuf,offset+10,nmb->header.arcount);
965 offset += 12;
966 if (nmb->header.qdcount) {
967 /* XXXX this doesn't handle a qdcount of > 1 */
968 if (len) {
969 /* Length check. */
970 int extra = put_nmb_name(NULL,offset,
971 &nmb->question.question_name);
972 if (offset + extra > len) {
973 return 0;
976 offset += put_nmb_name((char *)ubuf,offset,
977 &nmb->question.question_name);
978 if (buf) {
979 RSSVAL(ubuf,offset,nmb->question.question_type);
980 RSSVAL(ubuf,offset+2,nmb->question.question_class);
982 offset += 4;
985 if (nmb->header.ancount) {
986 if (len) {
987 /* Length check. */
988 int extra = put_res_rec(NULL,offset,nmb->answers,
989 nmb->header.ancount);
990 if (offset + extra > len) {
991 return 0;
994 offset += put_res_rec((char *)ubuf,offset,nmb->answers,
995 nmb->header.ancount);
998 if (nmb->header.nscount) {
999 if (len) {
1000 /* Length check. */
1001 int extra = put_res_rec(NULL,offset,nmb->nsrecs,
1002 nmb->header.nscount);
1003 if (offset + extra > len) {
1004 return 0;
1007 offset += put_res_rec((char *)ubuf,offset,nmb->nsrecs,
1008 nmb->header.nscount);
1012 * The spec says we must put compressed name pointers
1013 * in the following outgoing packets :
1014 * NAME_REGISTRATION_REQUEST, NAME_REFRESH_REQUEST,
1015 * NAME_RELEASE_REQUEST.
1018 if((nmb->header.response == False) &&
1019 ((nmb->header.opcode == NMB_NAME_REG_OPCODE) ||
1020 (nmb->header.opcode == NMB_NAME_RELEASE_OPCODE) ||
1021 (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_8) ||
1022 (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_9) ||
1023 (nmb->header.opcode == NMB_NAME_MULTIHOMED_REG_OPCODE)) &&
1024 (nmb->header.arcount == 1)) {
1026 if (len) {
1027 /* Length check. */
1028 int extra = put_compressed_name_ptr(NULL,offset,
1029 nmb->additional,12);
1030 if (offset + extra > len) {
1031 return 0;
1034 offset += put_compressed_name_ptr(ubuf,offset,
1035 nmb->additional,12);
1036 } else if (nmb->header.arcount) {
1037 if (len) {
1038 /* Length check. */
1039 int extra = put_res_rec(NULL,offset,nmb->additional,
1040 nmb->header.arcount);
1041 if (offset + extra > len) {
1042 return 0;
1045 offset += put_res_rec((char *)ubuf,offset,nmb->additional,
1046 nmb->header.arcount);
1048 return offset;
1051 /*******************************************************************
1052 Linearise a packet.
1053 ******************************************************************/
1055 int build_packet(char *buf, size_t buflen, struct packet_struct *p)
1057 int len = 0;
1059 switch (p->packet_type) {
1060 case NMB_PACKET:
1061 len = build_nmb(buf,buflen,p);
1062 break;
1064 case DGRAM_PACKET:
1065 len = build_dgram(buf,buflen,p);
1066 break;
1069 return len;
1072 /*******************************************************************
1073 Send a packet_struct.
1074 ******************************************************************/
1076 bool send_packet(struct packet_struct *p)
1078 char buf[1024];
1079 int len=0;
1081 memset(buf,'\0',sizeof(buf));
1083 len = build_packet(buf, sizeof(buf), p);
1085 if (!len)
1086 return(False);
1088 return(send_udp(p->fd,buf,len,p->ip,p->port));
1091 /****************************************************************************
1092 Receive a packet with timeout on a open UDP filedescriptor.
1093 The timeout is in milliseconds
1094 ***************************************************************************/
1096 struct packet_struct *receive_packet(int fd,enum packet_type type,int t)
1098 fd_set fds;
1099 struct timeval timeout;
1100 int ret;
1102 FD_ZERO(&fds);
1103 FD_SET(fd,&fds);
1104 timeout.tv_sec = t/1000;
1105 timeout.tv_usec = 1000*(t%1000);
1107 if ((ret = sys_select_intr(fd+1,&fds,NULL,NULL,&timeout)) == -1) {
1108 /* errno should be EBADF or EINVAL. */
1109 DEBUG(0,("select returned -1, errno = %s (%d)\n",
1110 strerror(errno), errno));
1111 return NULL;
1114 if (ret == 0) /* timeout */
1115 return NULL;
1117 if (FD_ISSET(fd,&fds))
1118 return(read_packet(fd,type));
1120 return(NULL);
1123 /****************************************************************************
1124 Receive a UDP/137 packet either via UDP or from the unexpected packet
1125 queue. The packet must be a reply packet and have the specified trn_id.
1126 The timeout is in milliseconds.
1127 ***************************************************************************/
1129 struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id)
1131 struct packet_struct *p;
1133 p = receive_packet(fd, NMB_PACKET, t);
1135 if (p && p->packet.nmb.header.response &&
1136 p->packet.nmb.header.name_trn_id == trn_id) {
1137 return p;
1139 if (p)
1140 free_packet(p);
1142 /* try the unexpected packet queue */
1143 return receive_unexpected(NMB_PACKET, trn_id, NULL);
1146 /****************************************************************************
1147 Receive a UDP/138 packet either via UDP or from the unexpected packet
1148 queue. The packet must be a reply packet and have the specified mailslot name
1149 The timeout is in milliseconds.
1150 ***************************************************************************/
1152 struct packet_struct *receive_dgram_packet(int fd, int t,
1153 const char *mailslot_name)
1155 struct packet_struct *p;
1157 p = receive_packet(fd, DGRAM_PACKET, t);
1159 if (p && match_mailslot_name(p, mailslot_name)) {
1160 return p;
1162 if (p)
1163 free_packet(p);
1165 /* try the unexpected packet queue */
1166 return receive_unexpected(DGRAM_PACKET, 0, mailslot_name);
1169 /****************************************************************************
1170 See if a datagram has the right mailslot name.
1171 ***************************************************************************/
1173 bool match_mailslot_name(struct packet_struct *p, const char *mailslot_name)
1175 struct dgram_packet *dgram = &p->packet.dgram;
1176 char *buf;
1178 buf = &dgram->data[0];
1179 buf -= 4;
1181 buf = smb_buf(buf);
1183 if (memcmp(buf, mailslot_name, strlen(mailslot_name)+1) == 0) {
1184 return True;
1187 return False;
1190 /****************************************************************************
1191 Return the number of bits that match between two len character buffers
1192 ***************************************************************************/
1194 int matching_len_bits(unsigned char *p1, unsigned char *p2, size_t len)
1196 size_t i, j;
1197 int ret = 0;
1198 for (i=0; i<len; i++) {
1199 if (p1[i] != p2[i])
1200 break;
1201 ret += 8;
1204 if (i==len)
1205 return ret;
1207 for (j=0; j<8; j++) {
1208 if ((p1[i] & (1<<(7-j))) != (p2[i] & (1<<(7-j))))
1209 break;
1210 ret++;
1213 return ret;
1216 static unsigned char sort_ip[4];
1218 /****************************************************************************
1219 Compare two query reply records.
1220 ***************************************************************************/
1222 static int name_query_comp(unsigned char *p1, unsigned char *p2)
1224 return matching_len_bits(p2+2, sort_ip, 4) -
1225 matching_len_bits(p1+2, sort_ip, 4);
1228 /****************************************************************************
1229 Sort a set of 6 byte name query response records so that the IPs that
1230 have the most leading bits in common with the specified address come first.
1231 ***************************************************************************/
1233 void sort_query_replies(char *data, int n, struct in_addr ip)
1235 if (n <= 1)
1236 return;
1238 putip(sort_ip, (char *)&ip);
1240 qsort(data, n, 6, QSORT_CAST name_query_comp);
1243 /****************************************************************************
1244 Interpret the weird netbios "name" into a unix fstring. Return the name type.
1245 ****************************************************************************/
1247 static int name_interpret(char *in, fstring name)
1249 int ret;
1250 int len = (*in++) / 2;
1251 fstring out_string;
1252 char *out = out_string;
1254 *out=0;
1256 if (len > 30 || len<1)
1257 return(0);
1259 while (len--) {
1260 if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
1261 *out = 0;
1262 return(0);
1264 *out = ((in[0]-'A')<<4) + (in[1]-'A');
1265 in += 2;
1266 out++;
1268 ret = out[-1];
1269 out[-1] = 0;
1271 #ifdef NETBIOS_SCOPE
1272 /* Handle any scope names */
1273 while(*in) {
1274 *out++ = '.'; /* Scope names are separated by periods */
1275 len = *(unsigned char *)in++;
1276 StrnCpy(out, in, len);
1277 out += len;
1278 *out=0;
1279 in += len;
1281 #endif
1282 pull_ascii_fstring(name, out_string);
1284 return(ret);
1287 /****************************************************************************
1288 Mangle a name into netbios format.
1289 Note: <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
1290 ****************************************************************************/
1292 int name_mangle( char *In, char *Out, char name_type )
1294 int i;
1295 int len;
1296 nstring buf;
1297 char *p = Out;
1299 /* Safely copy the input string, In, into buf[]. */
1300 if (strcmp(In,"*") == 0)
1301 put_name(buf, "*", '\0', 0x00);
1302 else {
1303 /* We use an fstring here as mb dos names can expend x3 when
1304 going to utf8. */
1305 fstring buf_unix;
1306 nstring buf_dos;
1308 pull_ascii_fstring(buf_unix, In);
1309 strupper_m(buf_unix);
1311 push_ascii_nstring(buf_dos, buf_unix);
1312 put_name(buf, buf_dos, ' ', name_type);
1315 /* Place the length of the first field into the output buffer. */
1316 p[0] = 32;
1317 p++;
1319 /* Now convert the name to the rfc1001/1002 format. */
1320 for( i = 0; i < MAX_NETBIOSNAME_LEN; i++ ) {
1321 p[i*2] = ( (buf[i] >> 4) & 0x000F ) + 'A';
1322 p[(i*2)+1] = (buf[i] & 0x000F) + 'A';
1324 p += 32;
1325 p[0] = '\0';
1327 /* Add the scope string. */
1328 for( i = 0, len = 0; *(global_scope()) != '\0'; i++, len++ ) {
1329 switch( (global_scope())[i] ) {
1330 case '\0':
1331 p[0] = len;
1332 if( len > 0 )
1333 p[len+1] = 0;
1334 return( name_len(Out) );
1335 case '.':
1336 p[0] = len;
1337 p += (len + 1);
1338 len = -1;
1339 break;
1340 default:
1341 p[len+1] = (global_scope())[i];
1342 break;
1346 return( name_len(Out) );
1349 /****************************************************************************
1350 Find a pointer to a netbios name.
1351 ****************************************************************************/
1353 static char *name_ptr(char *buf,int ofs)
1355 unsigned char c = *(unsigned char *)(buf+ofs);
1357 if ((c & 0xC0) == 0xC0) {
1358 uint16 l = RSVAL(buf, ofs) & 0x3FFF;
1359 DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
1360 return(buf + l);
1361 } else {
1362 return(buf+ofs);
1366 /****************************************************************************
1367 Extract a netbios name from a buf (into a unix string) return name type.
1368 ****************************************************************************/
1370 int name_extract(char *buf,int ofs, fstring name)
1372 char *p = name_ptr(buf,ofs);
1373 int d = PTR_DIFF(p,buf+ofs);
1375 name[0] = '\0';
1376 if (d < -50 || d > 50)
1377 return(0);
1378 return(name_interpret(p,name));
1381 /****************************************************************************
1382 Return the total storage length of a mangled name.
1383 ****************************************************************************/
1385 int name_len(char *s1)
1387 /* NOTE: this argument _must_ be unsigned */
1388 unsigned char *s = (unsigned char *)s1;
1389 int len;
1391 /* If the two high bits of the byte are set, return 2. */
1392 if (0xC0 == (*s & 0xC0))
1393 return(2);
1395 /* Add up the length bytes. */
1396 for (len = 1; (*s); s += (*s) + 1) {
1397 len += *s + 1;
1398 SMB_ASSERT(len < 80);
1401 return(len);