don't dereference null pointer
[Samba/gebeck_regimport.git] / source4 / libcli / nmblib.c
bloba875f4652eb7194b1163ea94372b1e161e69f661
1 /*
2 Unix SMB/CIFS implementation.
3 NBT netbios library routines
4 Copyright (C) Andrew Tridgell 1994-1998
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "includes.h"
24 static const struct opcode_names {
25 const char *nmb_opcode_name;
26 int opcode;
27 } nmb_header_opcode_names[] = {
28 {"Query", 0 },
29 {"Registration", 5 },
30 {"Release", 6 },
31 {"WACK", 7 },
32 {"Refresh", 8 },
33 {"Refresh(altcode)", 9 },
34 {"Multi-homed Registration", 15 },
35 {0, -1 }
38 /****************************************************************************
39 * Lookup a nmb opcode name.
40 ****************************************************************************/
41 static const char *lookup_opcode_name( int opcode )
43 const struct opcode_names *op_namep;
44 int i;
46 for(i = 0; nmb_header_opcode_names[i].nmb_opcode_name != 0; i++) {
47 op_namep = &nmb_header_opcode_names[i];
48 if(opcode == op_namep->opcode)
49 return op_namep->nmb_opcode_name;
51 return "<unknown opcode>";
54 /****************************************************************************
55 print out a res_rec structure
56 ****************************************************************************/
57 static void debug_nmb_res_rec(struct res_rec *res, const char *hdr)
59 int i, j;
61 DEBUGADD( 4, ( " %s: nmb_name=%s rr_type=%d rr_class=%d ttl=%d\n",
62 hdr,
63 nmb_namestr(&res->rr_name),
64 res->rr_type,
65 res->rr_class,
66 res->ttl ) );
68 if( res->rdlength == 0 || res->rdata == NULL )
69 return;
71 for (i = 0; i < res->rdlength; i+= 16)
73 DEBUGADD(4, (" %s %3x char ", hdr, i));
75 for (j = 0; j < 16; j++)
77 uchar x = res->rdata[i+j];
78 if (x < 32 || x > 127) x = '.';
80 if (i+j >= res->rdlength) break;
81 DEBUGADD(4, ("%c", x));
84 DEBUGADD(4, (" hex "));
86 for (j = 0; j < 16; j++)
88 if (i+j >= res->rdlength) break;
89 DEBUGADD(4, ("%02X", (uchar)res->rdata[i+j]));
92 DEBUGADD(4, ("\n"));
96 /****************************************************************************
97 process a nmb packet
98 ****************************************************************************/
99 void debug_nmb_packet(struct packet_struct *p)
101 struct nmb_packet *nmb = &p->packet.nmb;
103 if (DEBUGLVL(4)) {
104 DEBUG(4, ("nmb packet from %s(%d) header: id=%d opcode=%s(%d) response=%s\n",
105 inet_ntoa(p->ip), p->port,
106 nmb->header.name_trn_id,
107 lookup_opcode_name(nmb->header.opcode),
108 nmb->header.opcode,
109 BOOLSTR(nmb->header.response)));
110 DEBUG(4, (" header: flags: bcast=%s rec_avail=%s rec_des=%s trunc=%s auth=%s\n",
111 BOOLSTR(nmb->header.nm_flags.bcast),
112 BOOLSTR(nmb->header.nm_flags.recursion_available),
113 BOOLSTR(nmb->header.nm_flags.recursion_desired),
114 BOOLSTR(nmb->header.nm_flags.trunc),
115 BOOLSTR(nmb->header.nm_flags.authoritative)));
116 DEBUG(4, (" header: rcode=%d qdcount=%d ancount=%d nscount=%d arcount=%d\n",
117 nmb->header.rcode,
118 nmb->header.qdcount,
119 nmb->header.ancount,
120 nmb->header.nscount,
121 nmb->header.arcount));
124 if (nmb->header.qdcount)
126 DEBUGADD( 4, ( " question: q_name=%s q_type=%d q_class=%d\n",
127 nmb_namestr(&nmb->question.question_name),
128 nmb->question.question_type,
129 nmb->question.question_class) );
132 if (nmb->answers && nmb->header.ancount)
134 debug_nmb_res_rec(nmb->answers,"answers");
136 if (nmb->nsrecs && nmb->header.nscount)
138 debug_nmb_res_rec(nmb->nsrecs,"nsrecs");
140 if (nmb->additional && nmb->header.arcount)
142 debug_nmb_res_rec(nmb->additional,"additional");
146 /*******************************************************************
147 handle "compressed" name pointers
148 ******************************************************************/
149 static BOOL handle_name_ptrs(uchar *ubuf,int *offset,int length,
150 BOOL *got_pointer,int *ret)
152 int loop_count=0;
154 while ((ubuf[*offset] & 0xC0) == 0xC0) {
155 if (!*got_pointer) (*ret) += 2;
156 (*got_pointer)=True;
157 (*offset) = ((ubuf[*offset] & ~0xC0)<<8) | ubuf[(*offset)+1];
158 if (loop_count++ == 10 || (*offset) < 0 || (*offset)>(length-2)) {
159 return(False);
162 return(True);
165 /*******************************************************************
166 parse a nmb name from "compressed" format to something readable
167 return the space taken by the name, or 0 if the name is invalid
168 ******************************************************************/
169 static int parse_nmb_name(char *inbuf,int ofs,int length, struct nmb_name *name)
171 int m,n=0;
172 uchar *ubuf = (uchar *)inbuf;
173 int ret = 0;
174 BOOL got_pointer=False;
175 int loop_count=0;
176 int offset = ofs;
178 if (length - offset < 2)
179 return(0);
181 /* handle initial name pointers */
182 if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret))
183 return(0);
185 m = ubuf[offset];
187 if (!m)
188 return(0);
189 if ((m & 0xC0) || offset+m+2 > length)
190 return(0);
192 memset((char *)name,'\0',sizeof(*name));
194 /* the "compressed" part */
195 if (!got_pointer)
196 ret += m + 2;
197 offset++;
198 while (m > 0) {
199 uchar c1,c2;
200 c1 = ubuf[offset++]-'A';
201 c2 = ubuf[offset++]-'A';
202 if ((c1 & 0xF0) || (c2 & 0xF0) || (n > sizeof(name->name)-1))
203 return(0);
204 name->name[n++] = (c1<<4) | c2;
205 m -= 2;
207 name->name[n] = 0;
209 if (n==16) {
210 /* parse out the name type,
211 its always in the 16th byte of the name */
212 name->name_type = ((uchar)name->name[15]) & 0xff;
214 /* remove trailing spaces */
215 name->name[15] = 0;
216 n = 14;
217 while (n && name->name[n]==' ')
218 name->name[n--] = 0;
221 /* now the domain parts (if any) */
222 n = 0;
223 while (ubuf[offset]) {
224 /* we can have pointers within the domain part as well */
225 if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret))
226 return(0);
228 m = ubuf[offset];
230 * Don't allow null domain parts.
232 if (!m)
233 return(0);
234 if (!got_pointer)
235 ret += m+1;
236 if (n)
237 name->scope[n++] = '.';
238 if (m+2+offset>length || n+m+1>sizeof(name->scope))
239 return(0);
240 offset++;
241 while (m--)
242 name->scope[n++] = (char)ubuf[offset++];
245 * Watch for malicious loops.
247 if (loop_count++ == 10)
248 return 0;
250 name->scope[n++] = 0;
252 return(ret);
256 /*******************************************************************
257 put a compressed nmb name into a buffer. return the length of the
258 compressed name
260 compressed names are really weird. The "compression" doubles the
261 size. The idea is that it also means that compressed names conform
262 to the doman name system. See RFC1002.
263 ******************************************************************/
264 static int put_nmb_name(char *buf,int offset,struct nmb_name *name)
266 int ret,m;
267 fstring buf1;
268 char *p;
270 if (strcmp(name->name,"*") == 0) {
271 /* special case for wildcard name */
272 memset(buf1,'\0',20);
273 buf1[0] = '*';
274 buf1[15] = name->name_type;
275 } else {
276 slprintf(buf1, sizeof(buf1) - 1,"%-15.15s%c",name->name,name->name_type);
279 buf[offset] = 0x20;
281 ret = 34;
283 for (m=0;m<16;m++) {
284 buf[offset+1+2*m] = 'A' + ((buf1[m]>>4)&0xF);
285 buf[offset+2+2*m] = 'A' + (buf1[m]&0xF);
287 offset += 33;
289 buf[offset] = 0;
291 if (name->scope[0]) {
292 /* XXXX this scope handling needs testing */
293 ret += strlen(name->scope) + 1;
294 pstrcpy(&buf[offset+1],name->scope);
296 p = &buf[offset+1];
297 while ((p = strchr_m(p,'.'))) {
298 buf[offset] = PTR_DIFF(p,&buf[offset+1]);
299 offset += (buf[offset] + 1);
300 p = &buf[offset+1];
302 buf[offset] = strlen(&buf[offset+1]);
305 return(ret);
308 /*******************************************************************
309 useful for debugging messages
310 ******************************************************************/
311 char *nmb_namestr(struct nmb_name *n)
313 static int i=0;
314 static fstring ret[4];
315 char *p = ret[i];
317 if (!n->scope[0])
318 slprintf(p,sizeof(fstring)-1, "%s<%02x>",n->name,n->name_type);
319 else
320 slprintf(p,sizeof(fstring)-1, "%s<%02x>.%s",n->name,n->name_type,n->scope);
322 i = (i+1)%4;
323 return(p);
326 /*******************************************************************
327 allocate and parse some resource records
328 ******************************************************************/
329 static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length,
330 struct res_rec **recs, int count)
332 int i;
333 *recs = (struct res_rec *)malloc(sizeof(**recs)*count);
334 if (!*recs) return(False);
336 memset((char *)*recs,'\0',sizeof(**recs)*count);
338 for (i=0;i<count;i++) {
339 int l = parse_nmb_name(inbuf,*offset,length,&(*recs)[i].rr_name);
340 (*offset) += l;
341 if (!l || (*offset)+10 > length) {
342 SAFE_FREE(*recs);
343 return(False);
345 (*recs)[i].rr_type = RSVAL(inbuf,(*offset));
346 (*recs)[i].rr_class = RSVAL(inbuf,(*offset)+2);
347 (*recs)[i].ttl = RIVAL(inbuf,(*offset)+4);
348 (*recs)[i].rdlength = RSVAL(inbuf,(*offset)+8);
349 (*offset) += 10;
350 if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) ||
351 (*offset)+(*recs)[i].rdlength > length) {
352 SAFE_FREE(*recs);
353 return(False);
355 memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength);
356 (*offset) += (*recs)[i].rdlength;
358 return(True);
361 /*******************************************************************
362 put a resource record into a packet
363 ******************************************************************/
364 static int put_res_rec(char *buf,int offset,struct res_rec *recs,int count)
366 int ret=0;
367 int i;
369 for (i=0;i<count;i++) {
370 int l = put_nmb_name(buf,offset,&recs[i].rr_name);
371 offset += l;
372 ret += l;
373 RSSVAL(buf,offset,recs[i].rr_type);
374 RSSVAL(buf,offset+2,recs[i].rr_class);
375 RSIVAL(buf,offset+4,recs[i].ttl);
376 RSSVAL(buf,offset+8,recs[i].rdlength);
377 memcpy(buf+offset+10,recs[i].rdata,recs[i].rdlength);
378 offset += 10+recs[i].rdlength;
379 ret += 10+recs[i].rdlength;
382 return(ret);
385 /*******************************************************************
386 put a compressed name pointer record into a packet
387 ******************************************************************/
388 static int put_compressed_name_ptr(uchar *buf,int offset,struct res_rec *rec,int ptr_offset)
390 int ret=0;
391 buf[offset] = (0xC0 | ((ptr_offset >> 8) & 0xFF));
392 buf[offset+1] = (ptr_offset & 0xFF);
393 offset += 2;
394 ret += 2;
395 RSSVAL(buf,offset,rec->rr_type);
396 RSSVAL(buf,offset+2,rec->rr_class);
397 RSIVAL(buf,offset+4,rec->ttl);
398 RSSVAL(buf,offset+8,rec->rdlength);
399 memcpy(buf+offset+10,rec->rdata,rec->rdlength);
400 offset += 10+rec->rdlength;
401 ret += 10+rec->rdlength;
403 return(ret);
406 /*******************************************************************
407 parse a dgram packet. Return False if the packet can't be parsed
408 or is invalid for some reason, True otherwise
410 this is documented in section 4.4.1 of RFC1002
411 ******************************************************************/
412 static BOOL parse_dgram(char *inbuf,int length,struct dgram_packet *dgram)
414 int offset;
415 int flags;
417 memset((char *)dgram,'\0',sizeof(*dgram));
419 if (length < 14) return(False);
421 dgram->header.msg_type = CVAL(inbuf,0);
422 flags = CVAL(inbuf,1);
423 dgram->header.flags.node_type = (enum node_type)((flags>>2)&3);
424 if (flags & 1) dgram->header.flags.more = True;
425 if (flags & 2) dgram->header.flags.first = True;
426 dgram->header.dgm_id = RSVAL(inbuf,2);
427 putip((char *)&dgram->header.source_ip,inbuf+4);
428 dgram->header.source_port = RSVAL(inbuf,8);
429 dgram->header.dgm_length = RSVAL(inbuf,10);
430 dgram->header.packet_offset = RSVAL(inbuf,12);
432 offset = 14;
434 if (dgram->header.msg_type == 0x10 ||
435 dgram->header.msg_type == 0x11 ||
436 dgram->header.msg_type == 0x12) {
437 offset += parse_nmb_name(inbuf,offset,length,&dgram->source_name);
438 offset += parse_nmb_name(inbuf,offset,length,&dgram->dest_name);
441 if (offset >= length || (length-offset > sizeof(dgram->data)))
442 return(False);
444 dgram->datasize = length-offset;
445 memcpy(dgram->data,inbuf+offset,dgram->datasize);
447 return(True);
451 /*******************************************************************
452 parse a nmb packet. Return False if the packet can't be parsed
453 or is invalid for some reason, True otherwise
454 ******************************************************************/
455 static BOOL parse_nmb(char *inbuf,int length,struct nmb_packet *nmb)
457 int nm_flags,offset;
459 memset((char *)nmb,'\0',sizeof(*nmb));
461 if (length < 12) return(False);
463 /* parse the header */
464 nmb->header.name_trn_id = RSVAL(inbuf,0);
466 DEBUG(10,("parse_nmb: packet id = %d\n", nmb->header.name_trn_id));
468 nmb->header.opcode = (CVAL(inbuf,2) >> 3) & 0xF;
469 nmb->header.response = ((CVAL(inbuf,2)>>7)&1)?True:False;
470 nm_flags = ((CVAL(inbuf,2) & 0x7) << 4) + (CVAL(inbuf,3)>>4);
471 nmb->header.nm_flags.bcast = (nm_flags&1)?True:False;
472 nmb->header.nm_flags.recursion_available = (nm_flags&8)?True:False;
473 nmb->header.nm_flags.recursion_desired = (nm_flags&0x10)?True:False;
474 nmb->header.nm_flags.trunc = (nm_flags&0x20)?True:False;
475 nmb->header.nm_flags.authoritative = (nm_flags&0x40)?True:False;
476 nmb->header.rcode = CVAL(inbuf,3) & 0xF;
477 nmb->header.qdcount = RSVAL(inbuf,4);
478 nmb->header.ancount = RSVAL(inbuf,6);
479 nmb->header.nscount = RSVAL(inbuf,8);
480 nmb->header.arcount = RSVAL(inbuf,10);
482 if (nmb->header.qdcount) {
483 offset = parse_nmb_name(inbuf,12,length,&nmb->question.question_name);
484 if (!offset) return(False);
486 if (length - (12+offset) < 4) return(False);
487 nmb->question.question_type = RSVAL(inbuf,12+offset);
488 nmb->question.question_class = RSVAL(inbuf,12+offset+2);
490 offset += 12+4;
491 } else {
492 offset = 12;
495 /* and any resource records */
496 if (nmb->header.ancount &&
497 !parse_alloc_res_rec(inbuf,&offset,length,&nmb->answers,
498 nmb->header.ancount))
499 return(False);
501 if (nmb->header.nscount &&
502 !parse_alloc_res_rec(inbuf,&offset,length,&nmb->nsrecs,
503 nmb->header.nscount))
504 return(False);
506 if (nmb->header.arcount &&
507 !parse_alloc_res_rec(inbuf,&offset,length,&nmb->additional,
508 nmb->header.arcount))
509 return(False);
511 return(True);
514 /*******************************************************************
515 'Copy constructor' for an nmb packet
516 ******************************************************************/
517 static struct packet_struct *copy_nmb_packet(struct packet_struct *packet)
519 struct nmb_packet *nmb;
520 struct nmb_packet *copy_nmb;
521 struct packet_struct *pkt_copy;
523 if(( pkt_copy = (struct packet_struct *)malloc(sizeof(*packet))) == NULL)
525 DEBUG(0,("copy_nmb_packet: malloc fail.\n"));
526 return NULL;
529 /* Structure copy of entire thing. */
531 *pkt_copy = *packet;
533 /* Ensure this copy is not locked. */
534 pkt_copy->locked = False;
536 /* Ensure this copy has no resource records. */
537 nmb = &packet->packet.nmb;
538 copy_nmb = &pkt_copy->packet.nmb;
540 copy_nmb->answers = NULL;
541 copy_nmb->nsrecs = NULL;
542 copy_nmb->additional = NULL;
544 /* Now copy any resource records. */
546 if (nmb->answers)
548 if((copy_nmb->answers = (struct res_rec *)
549 malloc(nmb->header.ancount * sizeof(struct res_rec))) == NULL)
550 goto free_and_exit;
551 memcpy((char *)copy_nmb->answers, (char *)nmb->answers,
552 nmb->header.ancount * sizeof(struct res_rec));
554 if (nmb->nsrecs)
556 if((copy_nmb->nsrecs = (struct res_rec *)
557 malloc(nmb->header.nscount * sizeof(struct res_rec))) == NULL)
558 goto free_and_exit;
559 memcpy((char *)copy_nmb->nsrecs, (char *)nmb->nsrecs,
560 nmb->header.nscount * sizeof(struct res_rec));
562 if (nmb->additional)
564 if((copy_nmb->additional = (struct res_rec *)
565 malloc(nmb->header.arcount * sizeof(struct res_rec))) == NULL)
566 goto free_and_exit;
567 memcpy((char *)copy_nmb->additional, (char *)nmb->additional,
568 nmb->header.arcount * sizeof(struct res_rec));
571 return pkt_copy;
573 free_and_exit:
575 SAFE_FREE(copy_nmb->answers);
576 SAFE_FREE(copy_nmb->nsrecs);
577 SAFE_FREE(copy_nmb->additional);
578 SAFE_FREE(pkt_copy);
580 DEBUG(0,("copy_nmb_packet: malloc fail in resource records.\n"));
581 return NULL;
584 /*******************************************************************
585 'Copy constructor' for a dgram packet
586 ******************************************************************/
587 static struct packet_struct *copy_dgram_packet(struct packet_struct *packet)
589 struct packet_struct *pkt_copy;
591 if(( pkt_copy = (struct packet_struct *)malloc(sizeof(*packet))) == NULL)
593 DEBUG(0,("copy_dgram_packet: malloc fail.\n"));
594 return NULL;
597 /* Structure copy of entire thing. */
599 *pkt_copy = *packet;
601 /* Ensure this copy is not locked. */
602 pkt_copy->locked = False;
604 /* There are no additional pointers in a dgram packet,
605 we are finished. */
606 return pkt_copy;
609 /*******************************************************************
610 'Copy constructor' for a generic packet
611 ******************************************************************/
612 struct packet_struct *copy_packet(struct packet_struct *packet)
614 if(packet->packet_type == NMB_PACKET)
615 return copy_nmb_packet(packet);
616 else if (packet->packet_type == DGRAM_PACKET)
617 return copy_dgram_packet(packet);
618 return NULL;
621 /*******************************************************************
622 free up any resources associated with an nmb packet
623 ******************************************************************/
624 static void free_nmb_packet(struct nmb_packet *nmb)
626 SAFE_FREE(nmb->answers);
627 SAFE_FREE(nmb->nsrecs);
628 SAFE_FREE(nmb->additional);
631 /*******************************************************************
632 free up any resources associated with a dgram packet
633 ******************************************************************/
634 static void free_dgram_packet(struct dgram_packet *nmb)
636 /* We have nothing to do for a dgram packet. */
639 /*******************************************************************
640 free up any resources associated with a packet
641 ******************************************************************/
642 void free_packet(struct packet_struct *packet)
644 if (packet->locked)
645 return;
646 if (packet->packet_type == NMB_PACKET)
647 free_nmb_packet(&packet->packet.nmb);
648 else if (packet->packet_type == DGRAM_PACKET)
649 free_dgram_packet(&packet->packet.dgram);
650 ZERO_STRUCTPN(packet);
651 SAFE_FREE(packet);
654 /*******************************************************************
655 parse a packet buffer into a packet structure
656 ******************************************************************/
657 struct packet_struct *parse_packet(char *buf,int length,
658 enum packet_type packet_type)
660 struct packet_struct *p;
661 BOOL ok=False;
663 p = (struct packet_struct *)malloc(sizeof(*p));
664 if (!p) return(NULL);
666 p->next = NULL;
667 p->prev = NULL;
668 p->locked = False;
669 p->timestamp = time(NULL);
670 p->packet_type = packet_type;
672 switch (packet_type) {
673 case NMB_PACKET:
674 ok = parse_nmb(buf,length,&p->packet.nmb);
675 break;
677 case DGRAM_PACKET:
678 ok = parse_dgram(buf,length,&p->packet.dgram);
679 break;
682 if (!ok) {
683 free_packet(p);
684 return NULL;
687 return p;
690 /*******************************************************************
691 read a packet from a socket and parse it, returning a packet ready
692 to be used or put on the queue. This assumes a UDP socket
693 ******************************************************************/
694 struct packet_struct *read_packet(int fd,enum packet_type packet_type)
696 struct packet_struct *packet;
697 char buf[MAX_DGRAM_SIZE];
698 int length;
699 struct in_addr addr;
700 int port;
702 length = read_udp_socket(fd, buf, sizeof(buf), &addr, &port);
703 if (length < MIN_DGRAM_SIZE) return(NULL);
705 packet = parse_packet(buf, length, packet_type);
706 if (!packet) return NULL;
708 packet->fd = fd;
709 packet->ip = addr;
710 packet->port = port;
712 DEBUG(5,("Received a packet of len %d from (%s) port %d\n",
713 length, inet_ntoa(packet->ip), packet->port));
715 return packet;
719 /*******************************************************************
720 send a udp packet on a already open socket
721 ******************************************************************/
722 static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port)
724 BOOL ret = False;
725 int i;
726 struct sockaddr_in sock_out;
728 /* set the address and port */
729 memset((char *)&sock_out,'\0',sizeof(sock_out));
730 putip((char *)&sock_out.sin_addr,(char *)&ip);
731 sock_out.sin_port = htons( port );
732 sock_out.sin_family = AF_INET;
734 DEBUG( 5, ( "Sending a packet of len %d to (%s) on port %d\n",
735 len, inet_ntoa(ip), port ) );
738 * Patch to fix asynch error notifications from Linux kernel.
741 for (i = 0; i < 5; i++) {
742 ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out, sizeof(sock_out)) >= 0);
743 if (ret || errno != ECONNREFUSED)
744 break;
747 if (!ret)
748 DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n",
749 inet_ntoa(ip),port,strerror(errno)));
751 return(ret);
754 /*******************************************************************
755 build a dgram packet ready for sending
757 XXXX This currently doesn't handle packets too big for one
758 datagram. It should split them and use the packet_offset, more and
759 first flags to handle the fragmentation. Yuck.
761 [...but it isn't clear that we would ever need to send a
762 a fragmented NBT Datagram. The IP layer does its own
763 fragmentation to ensure that messages can fit into the path
764 MTU. It *is* important to be able to receive and rebuild
765 fragmented NBT datagrams, just in case someone out there
766 really has implemented this 'feature'. crh -)------ ]
768 ******************************************************************/
769 static int build_dgram(char *buf,struct packet_struct *p)
771 struct dgram_packet *dgram = &p->packet.dgram;
772 uchar *ubuf = (uchar *)buf;
773 int offset=0;
775 /* put in the header */
776 ubuf[0] = dgram->header.msg_type;
777 ubuf[1] = (((int)dgram->header.flags.node_type)<<2);
778 if (dgram->header.flags.more) ubuf[1] |= 1;
779 if (dgram->header.flags.first) ubuf[1] |= 2;
780 RSSVAL(ubuf,2,dgram->header.dgm_id);
781 putip(ubuf+4,(char *)&dgram->header.source_ip);
782 RSSVAL(ubuf,8,dgram->header.source_port);
783 RSSVAL(ubuf,12,dgram->header.packet_offset);
785 offset = 14;
787 if (dgram->header.msg_type == 0x10 ||
788 dgram->header.msg_type == 0x11 ||
789 dgram->header.msg_type == 0x12) {
790 offset += put_nmb_name((char *)ubuf,offset,&dgram->source_name);
791 offset += put_nmb_name((char *)ubuf,offset,&dgram->dest_name);
794 memcpy(ubuf+offset,dgram->data,dgram->datasize);
795 offset += dgram->datasize;
797 /* automatically set the dgm_length
798 * NOTE: RFC1002 says the dgm_length does *not*
799 * include the fourteen-byte header. crh
801 dgram->header.dgm_length = (offset - 14);
802 RSSVAL(ubuf,10,dgram->header.dgm_length);
804 return(offset);
807 /*******************************************************************
808 Build a nmb name
809 *******************************************************************/
811 void make_nmb_name( struct nmb_name *n, const char *name, int type)
813 memset( (char *)n, '\0', sizeof(struct nmb_name) );
814 push_ascii(n->name, name, 16, STR_TERMINATE|STR_UPPER);
815 n->name_type = (unsigned int)type & 0xFF;
816 StrnCpy( n->scope, lp_netbios_scope(), 63 );
817 strupper( n->scope );
820 /*******************************************************************
821 Compare two nmb names
822 ******************************************************************/
824 BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2)
826 return ((n1->name_type == n2->name_type) &&
827 strequal(n1->name ,n2->name ) &&
828 strequal(n1->scope,n2->scope));
831 /*******************************************************************
832 build a nmb packet ready for sending
834 XXXX this currently relies on not being passed something that expands
835 to a packet too big for the buffer. Eventually this should be
836 changed to set the trunc bit so the receiver can request the rest
837 via tcp (when that becomes supported)
838 ******************************************************************/
839 static int build_nmb(char *buf,struct packet_struct *p)
841 struct nmb_packet *nmb = &p->packet.nmb;
842 uchar *ubuf = (uchar *)buf;
843 int offset=0;
845 /* put in the header */
846 RSSVAL(ubuf,offset,nmb->header.name_trn_id);
847 ubuf[offset+2] = (nmb->header.opcode & 0xF) << 3;
848 if (nmb->header.response) ubuf[offset+2] |= (1<<7);
849 if (nmb->header.nm_flags.authoritative &&
850 nmb->header.response) ubuf[offset+2] |= 0x4;
851 if (nmb->header.nm_flags.trunc) ubuf[offset+2] |= 0x2;
852 if (nmb->header.nm_flags.recursion_desired) ubuf[offset+2] |= 0x1;
853 if (nmb->header.nm_flags.recursion_available &&
854 nmb->header.response) ubuf[offset+3] |= 0x80;
855 if (nmb->header.nm_flags.bcast) ubuf[offset+3] |= 0x10;
856 ubuf[offset+3] |= (nmb->header.rcode & 0xF);
858 RSSVAL(ubuf,offset+4,nmb->header.qdcount);
859 RSSVAL(ubuf,offset+6,nmb->header.ancount);
860 RSSVAL(ubuf,offset+8,nmb->header.nscount);
861 RSSVAL(ubuf,offset+10,nmb->header.arcount);
863 offset += 12;
864 if (nmb->header.qdcount) {
865 /* XXXX this doesn't handle a qdcount of > 1 */
866 offset += put_nmb_name((char *)ubuf,offset,&nmb->question.question_name);
867 RSSVAL(ubuf,offset,nmb->question.question_type);
868 RSSVAL(ubuf,offset+2,nmb->question.question_class);
869 offset += 4;
872 if (nmb->header.ancount)
873 offset += put_res_rec((char *)ubuf,offset,nmb->answers,
874 nmb->header.ancount);
876 if (nmb->header.nscount)
877 offset += put_res_rec((char *)ubuf,offset,nmb->nsrecs,
878 nmb->header.nscount);
881 * The spec says we must put compressed name pointers
882 * in the following outgoing packets :
883 * NAME_REGISTRATION_REQUEST, NAME_REFRESH_REQUEST,
884 * NAME_RELEASE_REQUEST.
887 if((nmb->header.response == False) &&
888 ((nmb->header.opcode == NMB_NAME_REG_OPCODE) ||
889 (nmb->header.opcode == NMB_NAME_RELEASE_OPCODE) ||
890 (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_8) ||
891 (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_9) ||
892 (nmb->header.opcode == NMB_NAME_MULTIHOMED_REG_OPCODE)) &&
893 (nmb->header.arcount == 1)) {
895 offset += put_compressed_name_ptr(ubuf,offset,nmb->additional,12);
897 } else if (nmb->header.arcount) {
898 offset += put_res_rec((char *)ubuf,offset,nmb->additional,
899 nmb->header.arcount);
901 return(offset);
905 /*******************************************************************
906 linearise a packet
907 ******************************************************************/
908 int build_packet(char *buf, struct packet_struct *p)
910 int len = 0;
912 switch (p->packet_type) {
913 case NMB_PACKET:
914 len = build_nmb(buf,p);
915 break;
917 case DGRAM_PACKET:
918 len = build_dgram(buf,p);
919 break;
922 return len;
925 /*******************************************************************
926 send a packet_struct
927 ******************************************************************/
928 BOOL send_packet(struct packet_struct *p)
930 char buf[1024];
931 int len=0;
933 memset(buf,'\0',sizeof(buf));
935 len = build_packet(buf, p);
937 if (!len) return(False);
939 return(send_udp(p->fd,buf,len,p->ip,p->port));
942 /****************************************************************************
943 receive a packet with timeout on a open UDP filedescriptor
944 The timeout is in milliseconds
945 ***************************************************************************/
946 struct packet_struct *receive_packet(int fd,enum packet_type type,int t)
948 fd_set fds;
949 struct timeval timeout;
950 int ret;
952 FD_ZERO(&fds);
953 FD_SET(fd,&fds);
954 timeout.tv_sec = t/1000;
955 timeout.tv_usec = 1000*(t%1000);
957 if ((ret = sys_select_intr(fd+1,&fds,NULL,NULL,&timeout)) == -1) {
958 /* errno should be EBADF or EINVAL. */
959 DEBUG(0,("select returned -1, errno = %s (%d)\n", strerror(errno), errno));
960 return NULL;
963 if (ret == 0) /* timeout */
964 return NULL;
966 if (FD_ISSET(fd,&fds))
967 return(read_packet(fd,type));
969 return(NULL);
973 /****************************************************************************
974 receive a UDP/137 packet either via UDP or from the unexpected packet
975 queue. The packet must be a reply packet and have the specified trn_id
976 The timeout is in milliseconds
977 ***************************************************************************/
978 struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id)
980 struct packet_struct *p;
982 p = receive_packet(fd, NMB_PACKET, t);
984 if (p && p->packet.nmb.header.response &&
985 p->packet.nmb.header.name_trn_id == trn_id) {
986 return p;
988 if (p) free_packet(p);
990 /* try the unexpected packet queue */
991 return receive_unexpected(NMB_PACKET, trn_id, NULL);
994 /****************************************************************************
995 receive a UDP/138 packet either via UDP or from the unexpected packet
996 queue. The packet must be a reply packet and have the specified mailslot name
997 The timeout is in milliseconds
998 ***************************************************************************/
999 struct packet_struct *receive_dgram_packet(int fd, int t, const char *mailslot_name)
1001 struct packet_struct *p;
1003 p = receive_packet(fd, DGRAM_PACKET, t);
1005 if (p && match_mailslot_name(p, mailslot_name)) {
1006 return p;
1008 if (p) free_packet(p);
1010 /* try the unexpected packet queue */
1011 return receive_unexpected(DGRAM_PACKET, 0, mailslot_name);
1015 /****************************************************************************
1016 see if a datagram has the right mailslot name
1017 ***************************************************************************/
1018 BOOL match_mailslot_name(struct packet_struct *p, const char *mailslot_name)
1020 struct dgram_packet *dgram = &p->packet.dgram;
1021 char *buf;
1023 buf = &dgram->data[0];
1024 buf -= 4;
1026 buf = smb_buf(buf);
1028 if (memcmp(buf, mailslot_name, strlen(mailslot_name)+1) == 0) {
1029 return True;
1032 return False;
1036 /****************************************************************************
1037 return the number of bits that match between two 4 character buffers
1038 ***************************************************************************/
1039 int matching_quad_bits(uchar *p1, uchar *p2)
1041 int i, j, ret = 0;
1042 for (i=0; i<4; i++) {
1043 if (p1[i] != p2[i]) break;
1044 ret += 8;
1047 if (i==4) return ret;
1049 for (j=0; j<8; j++) {
1050 if ((p1[i] & (1<<(7-j))) != (p2[i] & (1<<(7-j)))) break;
1051 ret++;
1054 return ret;
1058 static uchar sort_ip[4];
1060 /****************************************************************************
1061 compare two query reply records
1062 ***************************************************************************/
1063 static int name_query_comp(uchar *p1, uchar *p2)
1065 return matching_quad_bits(p2+2, sort_ip) - matching_quad_bits(p1+2, sort_ip);
1068 /****************************************************************************
1069 sort a set of 6 byte name query response records so that the IPs that
1070 have the most leading bits in common with the specified address come first
1071 ***************************************************************************/
1072 void sort_query_replies(char *data, int n, struct in_addr ip)
1074 if (n <= 1) return;
1076 putip(sort_ip, (char *)&ip);
1078 qsort(data, n, 6, QSORT_CAST name_query_comp);
1082 #define TRUNCATE_NETBIOS_NAME 1
1084 /*******************************************************************
1085 convert, possibly using a stupid microsoft-ism which has destroyed
1086 the transport independence of netbios (for CIFS vendors that usually
1087 use the Win95-type methods, not for NT to NT communication, which uses
1088 DCE/RPC and therefore full-length unicode strings...) a dns name into
1089 a netbios name.
1091 the netbios name (NOT necessarily null-terminated) is truncated to 15
1092 characters.
1094 ******************************************************************/
1095 char *dns_to_netbios_name(char *dns_name)
1097 static char netbios_name[16];
1098 int i;
1099 StrnCpy(netbios_name, dns_name, 15);
1100 netbios_name[15] = 0;
1102 #ifdef TRUNCATE_NETBIOS_NAME
1103 /* ok. this is because of a stupid microsoft-ism. if the called host
1104 name contains a '.', microsoft clients expect you to truncate the
1105 netbios name up to and including the '.' this even applies, by
1106 mistake, to workgroup (domain) names, which is _really_ daft.
1108 for (i = 15; i >= 0; i--)
1110 if (netbios_name[i] == '.')
1112 netbios_name[i] = 0;
1113 break;
1116 #endif /* TRUNCATE_NETBIOS_NAME */
1118 return netbios_name;
1122 /****************************************************************************
1123 interpret the weird netbios "name". Return the name type
1124 ****************************************************************************/
1125 static int name_interpret(char *in,char *out)
1127 int ret;
1128 int len = (*in++) / 2;
1130 *out=0;
1132 if (len > 30 || len<1) return(0);
1134 while (len--)
1136 if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
1137 *out = 0;
1138 return(0);
1140 *out = ((in[0]-'A')<<4) + (in[1]-'A');
1141 in += 2;
1142 out++;
1144 *out = 0;
1145 ret = out[-1];
1147 #ifdef NETBIOS_SCOPE
1148 /* Handle any scope names */
1149 while(*in)
1151 *out++ = '.'; /* Scope names are separated by periods */
1152 len = *(uchar *)in++;
1153 StrnCpy(out, in, len);
1154 out += len;
1155 *out=0;
1156 in += len;
1158 #endif
1159 return(ret);
1163 /****************************************************************************
1164 return the number of bytes that would be occupied by the result of
1165 name_mangle()
1166 ****************************************************************************/
1167 uint_t nbt_mangled_name_len(void)
1169 const char *scope = lp_netbios_scope();
1170 uint_t ret = 34;
1171 if (scope && *scope) {
1172 ret += strlen(scope) + 1;
1174 return ret;
1177 /****************************************************************************
1178 mangle a name into netbios format
1180 Note: <Out> must be nbt_mangled_name_len() in length
1181 ****************************************************************************/
1182 int name_mangle(char *In, char *Out, char name_type)
1184 int i;
1185 int c;
1186 int len;
1187 char buf[20];
1188 char *p = Out;
1189 const char *scope = lp_netbios_scope();
1191 /* Safely copy the input string, In, into buf[]. */
1192 memset( buf, 0, 20 );
1193 if (strcmp(In,"*") == 0) {
1194 buf[0] = '*';
1195 } else {
1196 slprintf( buf, sizeof(buf) - 1, "%-15.15s%c", In, name_type);
1199 /* Place the length of the first field into the output buffer. */
1200 p[0] = 32;
1201 p++;
1203 /* Now convert the name to the rfc1001/1002 format. */
1204 for ( i = 0; i < 16; i++ ) {
1205 c = toupper( buf[i] );
1206 p[i*2] = ( (c >> 4) & 0xF ) + 'A';
1207 p[(i*2)+1] = (c & 0xF) + 'A';
1209 p += 32;
1210 p[0] = '\0';
1212 if (!scope || !*scope) {
1213 return name_len(Out);
1216 /* Add the scope string. */
1217 for (i = 0, len = 0; scope[i]; i++, len++) {
1218 switch(scope[i]) {
1219 case '.':
1220 p[0] = len;
1221 p += (len + 1);
1222 len = -1;
1223 break;
1224 default:
1225 p[len+1] = scope[i];
1226 break;
1230 p[0] = len;
1231 if (len > 0) {
1232 p[len+1] = 0;
1235 return name_len(Out);
1238 /****************************************************************************
1239 find a pointer to a netbios name
1240 ****************************************************************************/
1241 static char *name_ptr(char *buf,int ofs)
1243 uchar c = *(uchar *)(buf+ofs);
1245 if ((c & 0xC0) == 0xC0)
1247 uint16 l = RSVAL(buf, ofs) & 0x3FFF;
1248 DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
1249 return(buf + l);
1251 else
1252 return(buf+ofs);
1255 /****************************************************************************
1256 extract a netbios name from a buf
1257 ****************************************************************************/
1258 int name_extract(char *buf,int ofs,char *name)
1260 char *p = name_ptr(buf,ofs);
1261 int d = PTR_DIFF(p,buf+ofs);
1262 pstrcpy(name,"");
1263 if (d < -50 || d > 50) return(0);
1264 return(name_interpret(p,name));
1267 /****************************************************************************
1268 return the total storage length of a mangled name
1269 ****************************************************************************/
1270 int name_len(char *s1)
1272 /* NOTE: this argument _must_ be unsigned */
1273 uchar *s = (uchar *)s1;
1274 int len;
1276 /* If the two high bits of the byte are set, return 2. */
1277 if (0xC0 == (*s & 0xC0))
1278 return(2);
1280 /* Add up the length bytes. */
1281 for (len = 1; (*s); s += (*s) + 1) {
1282 len += *s + 1;
1283 SMB_ASSERT(len < 80);
1286 return(len);
1287 } /* name_len */