r616: Bug #1333.
[Samba/gebeck_regimport.git] / source3 / libsmb / nmblib.c
blob3c25eba744f37e1d2ccd644716e91ccf6ab3e0ef
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 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 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 rec_des=%s trunc=%s auth=%s\n",
117 BOOLSTR(nmb->header.nm_flags.bcast),
118 BOOLSTR(nmb->header.nm_flags.recursion_available),
119 BOOLSTR(nmb->header.nm_flags.recursion_desired),
120 BOOLSTR(nmb->header.nm_flags.trunc),
121 BOOLSTR(nmb->header.nm_flags.authoritative) );
122 dbgtext( " header: rcode=%d qdcount=%d ancount=%d nscount=%d arcount=%d\n",
123 nmb->header.rcode,
124 nmb->header.qdcount,
125 nmb->header.ancount,
126 nmb->header.nscount,
127 nmb->header.arcount );
130 if (nmb->header.qdcount) {
131 DEBUGADD( 4, ( " question: q_name=%s q_type=%d q_class=%d\n",
132 nmb_namestr(&nmb->question.question_name),
133 nmb->question.question_type,
134 nmb->question.question_class) );
137 if (nmb->answers && nmb->header.ancount) {
138 debug_nmb_res_rec(nmb->answers,"answers");
140 if (nmb->nsrecs && nmb->header.nscount) {
141 debug_nmb_res_rec(nmb->nsrecs,"nsrecs");
143 if (nmb->additional && nmb->header.arcount) {
144 debug_nmb_res_rec(nmb->additional,"additional");
148 /*******************************************************************
149 Handle "compressed" name pointers.
150 ******************************************************************/
152 static BOOL handle_name_ptrs(unsigned char *ubuf,int *offset,int length,
153 BOOL *got_pointer,int *ret)
155 int loop_count=0;
157 while ((ubuf[*offset] & 0xC0) == 0xC0) {
158 if (!*got_pointer)
159 (*ret) += 2;
160 (*got_pointer)=True;
161 (*offset) = ((ubuf[*offset] & ~0xC0)<<8) | ubuf[(*offset)+1];
162 if (loop_count++ == 10 || (*offset) < 0 || (*offset)>(length-2)) {
163 return(False);
166 return(True);
169 /*******************************************************************
170 Parse a nmb name from "compressed" format to something readable
171 return the space taken by the name, or 0 if the name is invalid
172 ******************************************************************/
174 static int parse_nmb_name(char *inbuf,int ofs,int length, struct nmb_name *name)
176 int m,n=0;
177 unsigned char *ubuf = (unsigned char *)inbuf;
178 int ret = 0;
179 BOOL got_pointer=False;
180 int loop_count=0;
181 int offset = ofs;
183 if (length - offset < 2)
184 return(0);
186 /* handle initial name pointers */
187 if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret))
188 return(0);
190 m = ubuf[offset];
192 if (!m)
193 return(0);
194 if ((m & 0xC0) || offset+m+2 > length)
195 return(0);
197 memset((char *)name,'\0',sizeof(*name));
199 /* the "compressed" part */
200 if (!got_pointer)
201 ret += m + 2;
202 offset++;
203 while (m > 0) {
204 unsigned char c1,c2;
205 c1 = ubuf[offset++]-'A';
206 c2 = ubuf[offset++]-'A';
207 if ((c1 & 0xF0) || (c2 & 0xF0) || (n > sizeof(name->name)-1))
208 return(0);
209 name->name[n++] = (c1<<4) | c2;
210 m -= 2;
212 name->name[n] = 0;
214 if (n==MAX_NETBIOSNAME_LEN) {
215 /* parse out the name type, its always in the 16th byte of the name */
216 name->name_type = ((unsigned char)name->name[15]) & 0xff;
218 /* remove trailing spaces */
219 name->name[15] = 0;
220 n = 14;
221 while (n && name->name[n]==' ')
222 name->name[n--] = 0;
225 /* now the domain parts (if any) */
226 n = 0;
227 while (ubuf[offset]) {
228 /* we can have pointers within the domain part as well */
229 if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret))
230 return(0);
232 m = ubuf[offset];
234 * Don't allow null domain parts.
236 if (!m)
237 return(0);
238 if (!got_pointer)
239 ret += m+1;
240 if (n)
241 name->scope[n++] = '.';
242 if (m+2+offset>length || n+m+1>sizeof(name->scope))
243 return(0);
244 offset++;
245 while (m--)
246 name->scope[n++] = (char)ubuf[offset++];
249 * Watch for malicious loops.
251 if (loop_count++ == 10)
252 return 0;
254 name->scope[n++] = 0;
256 return(ret);
259 /****************************************************************************
260 Put a netbios name, padding(s) and a name type into a 16 character buffer.
261 name is already in DOS charset.
262 [15 bytes name + padding][1 byte name type].
263 ****************************************************************************/
265 static void put_name(char *dest, const char *name, int pad, unsigned int name_type)
267 size_t len = strlen(name);
269 memcpy(dest, name, (len < MAX_NETBIOSNAME_LEN) ? len : MAX_NETBIOSNAME_LEN - 1);
270 if (len < MAX_NETBIOSNAME_LEN - 1) {
271 memset(dest + len, pad, MAX_NETBIOSNAME_LEN - 1 - len);
273 dest[MAX_NETBIOSNAME_LEN - 1] = name_type;
276 /*******************************************************************
277 Put a compressed nmb name into a buffer. Return the length of the
278 compressed name.
280 Compressed names are really weird. The "compression" doubles the
281 size. The idea is that it also means that compressed names conform
282 to the doman name system. See RFC1002.
283 ******************************************************************/
285 static int put_nmb_name(char *buf,int offset,struct nmb_name *name)
287 int ret,m;
288 nstring buf1;
289 char *p;
291 if (strcmp(name->name,"*") == 0) {
292 /* special case for wildcard name */
293 put_name(buf1, "*", '\0', name->name_type);
294 } else {
295 put_name(buf1, name->name, ' ', name->name_type);
298 buf[offset] = 0x20;
300 ret = 34;
302 for (m=0;m<MAX_NETBIOSNAME_LEN;m++) {
303 buf[offset+1+2*m] = 'A' + ((buf1[m]>>4)&0xF);
304 buf[offset+2+2*m] = 'A' + (buf1[m]&0xF);
306 offset += 33;
308 buf[offset] = 0;
310 if (name->scope[0]) {
311 /* XXXX this scope handling needs testing */
312 ret += strlen(name->scope) + 1;
313 safe_strcpy(&buf[offset+1],name->scope,sizeof(name->scope));
315 p = &buf[offset+1];
316 while ((p = strchr_m(p,'.'))) {
317 buf[offset] = PTR_DIFF(p,&buf[offset+1]);
318 offset += (buf[offset] + 1);
319 p = &buf[offset+1];
321 buf[offset] = strlen(&buf[offset+1]);
324 return(ret);
327 /*******************************************************************
328 Useful for debugging messages.
329 ******************************************************************/
331 char *nmb_namestr(struct nmb_name *n)
333 static int i=0;
334 static fstring ret[4];
335 fstring name;
336 char *p = ret[i];
338 pull_ascii_fstring(name, n->name);
339 if (!n->scope[0])
340 slprintf(p,sizeof(fstring)-1, "%s<%02x>",name,n->name_type);
341 else
342 slprintf(p,sizeof(fstring)-1, "%s<%02x>.%s",name,n->name_type,n->scope);
344 i = (i+1)%4;
345 return(p);
348 /*******************************************************************
349 Allocate and parse some resource records.
350 ******************************************************************/
352 static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length,
353 struct res_rec **recs, int count)
355 int i;
357 *recs = (struct res_rec *)malloc(sizeof(**recs)*count);
358 if (!*recs)
359 return(False);
361 memset((char *)*recs,'\0',sizeof(**recs)*count);
363 for (i=0;i<count;i++) {
364 int l = parse_nmb_name(inbuf,*offset,length,&(*recs)[i].rr_name);
365 (*offset) += l;
366 if (!l || (*offset)+10 > length) {
367 SAFE_FREE(*recs);
368 return(False);
370 (*recs)[i].rr_type = RSVAL(inbuf,(*offset));
371 (*recs)[i].rr_class = RSVAL(inbuf,(*offset)+2);
372 (*recs)[i].ttl = RIVAL(inbuf,(*offset)+4);
373 (*recs)[i].rdlength = RSVAL(inbuf,(*offset)+8);
374 (*offset) += 10;
375 if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) ||
376 (*offset)+(*recs)[i].rdlength > length) {
377 SAFE_FREE(*recs);
378 return(False);
380 memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength);
381 (*offset) += (*recs)[i].rdlength;
383 return(True);
386 /*******************************************************************
387 Put a resource record into a packet.
388 ******************************************************************/
390 static int put_res_rec(char *buf,int offset,struct res_rec *recs,int count)
392 int ret=0;
393 int i;
395 for (i=0;i<count;i++) {
396 int l = put_nmb_name(buf,offset,&recs[i].rr_name);
397 offset += l;
398 ret += l;
399 RSSVAL(buf,offset,recs[i].rr_type);
400 RSSVAL(buf,offset+2,recs[i].rr_class);
401 RSIVAL(buf,offset+4,recs[i].ttl);
402 RSSVAL(buf,offset+8,recs[i].rdlength);
403 memcpy(buf+offset+10,recs[i].rdata,recs[i].rdlength);
404 offset += 10+recs[i].rdlength;
405 ret += 10+recs[i].rdlength;
408 return(ret);
411 /*******************************************************************
412 Put a compressed name pointer record into a packet.
413 ******************************************************************/
415 static int put_compressed_name_ptr(unsigned char *buf,int offset,struct res_rec *rec,int ptr_offset)
417 int ret=0;
418 buf[offset] = (0xC0 | ((ptr_offset >> 8) & 0xFF));
419 buf[offset+1] = (ptr_offset & 0xFF);
420 offset += 2;
421 ret += 2;
422 RSSVAL(buf,offset,rec->rr_type);
423 RSSVAL(buf,offset+2,rec->rr_class);
424 RSIVAL(buf,offset+4,rec->ttl);
425 RSSVAL(buf,offset+8,rec->rdlength);
426 memcpy(buf+offset+10,rec->rdata,rec->rdlength);
427 offset += 10+rec->rdlength;
428 ret += 10+rec->rdlength;
430 return(ret);
433 /*******************************************************************
434 Parse a dgram packet. Return False if the packet can't be parsed
435 or is invalid for some reason, True otherwise.
437 This is documented in section 4.4.1 of RFC1002.
438 ******************************************************************/
440 static BOOL parse_dgram(char *inbuf,int length,struct dgram_packet *dgram)
442 int offset;
443 int flags;
445 memset((char *)dgram,'\0',sizeof(*dgram));
447 if (length < 14)
448 return(False);
450 dgram->header.msg_type = CVAL(inbuf,0);
451 flags = CVAL(inbuf,1);
452 dgram->header.flags.node_type = (enum node_type)((flags>>2)&3);
453 if (flags & 1)
454 dgram->header.flags.more = True;
455 if (flags & 2)
456 dgram->header.flags.first = True;
457 dgram->header.dgm_id = RSVAL(inbuf,2);
458 putip((char *)&dgram->header.source_ip,inbuf+4);
459 dgram->header.source_port = RSVAL(inbuf,8);
460 dgram->header.dgm_length = RSVAL(inbuf,10);
461 dgram->header.packet_offset = RSVAL(inbuf,12);
463 offset = 14;
465 if (dgram->header.msg_type == 0x10 ||
466 dgram->header.msg_type == 0x11 ||
467 dgram->header.msg_type == 0x12) {
468 offset += parse_nmb_name(inbuf,offset,length,&dgram->source_name);
469 offset += parse_nmb_name(inbuf,offset,length,&dgram->dest_name);
472 if (offset >= length || (length-offset > sizeof(dgram->data)))
473 return(False);
475 dgram->datasize = length-offset;
476 memcpy(dgram->data,inbuf+offset,dgram->datasize);
478 return(True);
481 /*******************************************************************
482 Parse a nmb packet. Return False if the packet can't be parsed
483 or is invalid for some reason, True otherwise.
484 ******************************************************************/
486 static BOOL parse_nmb(char *inbuf,int length,struct nmb_packet *nmb)
488 int nm_flags,offset;
490 memset((char *)nmb,'\0',sizeof(*nmb));
492 if (length < 12)
493 return(False);
495 /* parse the header */
496 nmb->header.name_trn_id = RSVAL(inbuf,0);
498 DEBUG(10,("parse_nmb: packet id = %d\n", nmb->header.name_trn_id));
500 nmb->header.opcode = (CVAL(inbuf,2) >> 3) & 0xF;
501 nmb->header.response = ((CVAL(inbuf,2)>>7)&1)?True:False;
502 nm_flags = ((CVAL(inbuf,2) & 0x7) << 4) + (CVAL(inbuf,3)>>4);
503 nmb->header.nm_flags.bcast = (nm_flags&1)?True:False;
504 nmb->header.nm_flags.recursion_available = (nm_flags&8)?True:False;
505 nmb->header.nm_flags.recursion_desired = (nm_flags&0x10)?True:False;
506 nmb->header.nm_flags.trunc = (nm_flags&0x20)?True:False;
507 nmb->header.nm_flags.authoritative = (nm_flags&0x40)?True:False;
508 nmb->header.rcode = CVAL(inbuf,3) & 0xF;
509 nmb->header.qdcount = RSVAL(inbuf,4);
510 nmb->header.ancount = RSVAL(inbuf,6);
511 nmb->header.nscount = RSVAL(inbuf,8);
512 nmb->header.arcount = RSVAL(inbuf,10);
514 if (nmb->header.qdcount) {
515 offset = parse_nmb_name(inbuf,12,length,&nmb->question.question_name);
516 if (!offset)
517 return(False);
519 if (length - (12+offset) < 4)
520 return(False);
521 nmb->question.question_type = RSVAL(inbuf,12+offset);
522 nmb->question.question_class = RSVAL(inbuf,12+offset+2);
524 offset += 12+4;
525 } else {
526 offset = 12;
529 /* and any resource records */
530 if (nmb->header.ancount && !parse_alloc_res_rec(inbuf,&offset,length,&nmb->answers,
531 nmb->header.ancount))
532 return(False);
534 if (nmb->header.nscount && !parse_alloc_res_rec(inbuf,&offset,length,&nmb->nsrecs,
535 nmb->header.nscount))
536 return(False);
538 if (nmb->header.arcount && !parse_alloc_res_rec(inbuf,&offset,length,&nmb->additional,
539 nmb->header.arcount))
540 return(False);
542 return(True);
545 /*******************************************************************
546 'Copy constructor' for an nmb packet.
547 ******************************************************************/
549 static struct packet_struct *copy_nmb_packet(struct packet_struct *packet)
551 struct nmb_packet *nmb;
552 struct nmb_packet *copy_nmb;
553 struct packet_struct *pkt_copy;
555 if(( pkt_copy = (struct packet_struct *)malloc(sizeof(*packet))) == NULL) {
556 DEBUG(0,("copy_nmb_packet: malloc fail.\n"));
557 return NULL;
560 /* Structure copy of entire thing. */
562 *pkt_copy = *packet;
564 /* Ensure this copy is not locked. */
565 pkt_copy->locked = False;
567 /* Ensure this copy has no resource records. */
568 nmb = &packet->packet.nmb;
569 copy_nmb = &pkt_copy->packet.nmb;
571 copy_nmb->answers = NULL;
572 copy_nmb->nsrecs = NULL;
573 copy_nmb->additional = NULL;
575 /* Now copy any resource records. */
577 if (nmb->answers) {
578 if((copy_nmb->answers = (struct res_rec *)
579 malloc(nmb->header.ancount * sizeof(struct res_rec))) == NULL)
580 goto free_and_exit;
581 memcpy((char *)copy_nmb->answers, (char *)nmb->answers,
582 nmb->header.ancount * sizeof(struct res_rec));
584 if (nmb->nsrecs) {
585 if((copy_nmb->nsrecs = (struct res_rec *)
586 malloc(nmb->header.nscount * sizeof(struct res_rec))) == NULL)
587 goto free_and_exit;
588 memcpy((char *)copy_nmb->nsrecs, (char *)nmb->nsrecs,
589 nmb->header.nscount * sizeof(struct res_rec));
591 if (nmb->additional) {
592 if((copy_nmb->additional = (struct res_rec *)
593 malloc(nmb->header.arcount * sizeof(struct res_rec))) == NULL)
594 goto free_and_exit;
595 memcpy((char *)copy_nmb->additional, (char *)nmb->additional,
596 nmb->header.arcount * sizeof(struct res_rec));
599 return pkt_copy;
601 free_and_exit:
603 SAFE_FREE(copy_nmb->answers);
604 SAFE_FREE(copy_nmb->nsrecs);
605 SAFE_FREE(copy_nmb->additional);
606 SAFE_FREE(pkt_copy);
608 DEBUG(0,("copy_nmb_packet: malloc fail in resource records.\n"));
609 return NULL;
612 /*******************************************************************
613 'Copy constructor' for a dgram packet.
614 ******************************************************************/
616 static struct packet_struct *copy_dgram_packet(struct packet_struct *packet)
618 struct packet_struct *pkt_copy;
620 if(( pkt_copy = (struct packet_struct *)malloc(sizeof(*packet))) == NULL) {
621 DEBUG(0,("copy_dgram_packet: malloc fail.\n"));
622 return NULL;
625 /* Structure copy of entire thing. */
627 *pkt_copy = *packet;
629 /* Ensure this copy is not locked. */
630 pkt_copy->locked = False;
632 /* There are no additional pointers in a dgram packet,
633 we are finished. */
634 return pkt_copy;
637 /*******************************************************************
638 'Copy constructor' for a generic packet.
639 ******************************************************************/
641 struct packet_struct *copy_packet(struct packet_struct *packet)
643 if(packet->packet_type == NMB_PACKET)
644 return copy_nmb_packet(packet);
645 else if (packet->packet_type == DGRAM_PACKET)
646 return copy_dgram_packet(packet);
647 return NULL;
650 /*******************************************************************
651 Free up any resources associated with an nmb packet.
652 ******************************************************************/
654 static void free_nmb_packet(struct nmb_packet *nmb)
656 SAFE_FREE(nmb->answers);
657 SAFE_FREE(nmb->nsrecs);
658 SAFE_FREE(nmb->additional);
661 /*******************************************************************
662 Free up any resources associated with a dgram packet.
663 ******************************************************************/
665 static void free_dgram_packet(struct dgram_packet *nmb)
667 /* We have nothing to do for a dgram packet. */
670 /*******************************************************************
671 Free up any resources associated with a packet.
672 ******************************************************************/
674 void free_packet(struct packet_struct *packet)
676 if (packet->locked)
677 return;
678 if (packet->packet_type == NMB_PACKET)
679 free_nmb_packet(&packet->packet.nmb);
680 else if (packet->packet_type == DGRAM_PACKET)
681 free_dgram_packet(&packet->packet.dgram);
682 ZERO_STRUCTPN(packet);
683 SAFE_FREE(packet);
686 /*******************************************************************
687 Parse a packet buffer into a packet structure.
688 ******************************************************************/
690 struct packet_struct *parse_packet(char *buf,int length,
691 enum packet_type packet_type)
693 extern struct in_addr lastip;
694 extern int lastport;
695 struct packet_struct *p;
696 BOOL ok=False;
698 p = (struct packet_struct *)malloc(sizeof(*p));
699 if (!p)
700 return(NULL);
702 p->next = NULL;
703 p->prev = NULL;
704 p->ip = lastip;
705 p->port = lastport;
706 p->locked = False;
707 p->timestamp = time(NULL);
708 p->packet_type = packet_type;
710 switch (packet_type) {
711 case NMB_PACKET:
712 ok = parse_nmb(buf,length,&p->packet.nmb);
713 break;
715 case DGRAM_PACKET:
716 ok = parse_dgram(buf,length,&p->packet.dgram);
717 break;
720 if (!ok) {
721 free_packet(p);
722 return NULL;
725 return p;
728 /*******************************************************************
729 Read a packet from a socket and parse it, returning a packet ready
730 to be used or put on the queue. This assumes a UDP socket.
731 ******************************************************************/
733 struct packet_struct *read_packet(int fd,enum packet_type packet_type)
735 struct packet_struct *packet;
736 char buf[MAX_DGRAM_SIZE];
737 int length;
739 length = read_udp_socket(fd,buf,sizeof(buf));
740 if (length < MIN_DGRAM_SIZE)
741 return(NULL);
743 packet = parse_packet(buf, length, packet_type);
744 if (!packet)
745 return NULL;
747 packet->fd = fd;
749 num_good_receives++;
751 DEBUG(5,("Received a packet of len %d from (%s) port %d\n",
752 length, inet_ntoa(packet->ip), packet->port ) );
754 return(packet);
757 /*******************************************************************
758 Send a udp packet on a already open socket.
759 ******************************************************************/
761 static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port)
763 BOOL ret = False;
764 int i;
765 struct sockaddr_in sock_out;
767 /* set the address and port */
768 memset((char *)&sock_out,'\0',sizeof(sock_out));
769 putip((char *)&sock_out.sin_addr,(char *)&ip);
770 sock_out.sin_port = htons( port );
771 sock_out.sin_family = AF_INET;
773 DEBUG( 5, ( "Sending a packet of len %d to (%s) on port %d\n",
774 len, inet_ntoa(ip), port ) );
777 * Patch to fix asynch error notifications from Linux kernel.
780 for (i = 0; i < 5; i++) {
781 ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out, sizeof(sock_out)) >= 0);
782 if (ret || errno != ECONNREFUSED)
783 break;
786 if (!ret)
787 DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n",
788 inet_ntoa(ip),port,strerror(errno)));
790 if (ret)
791 num_good_sends++;
793 return(ret);
796 /*******************************************************************
797 Build a dgram packet ready for sending.
799 XXXX This currently doesn't handle packets too big for one
800 datagram. It should split them and use the packet_offset, more and
801 first flags to handle the fragmentation. Yuck.
803 [...but it isn't clear that we would ever need to send a
804 a fragmented NBT Datagram. The IP layer does its own
805 fragmentation to ensure that messages can fit into the path
806 MTU. It *is* important to be able to receive and rebuild
807 fragmented NBT datagrams, just in case someone out there
808 really has implemented this 'feature'. crh -)------ ]
810 ******************************************************************/
812 static int build_dgram(char *buf,struct packet_struct *p)
814 struct dgram_packet *dgram = &p->packet.dgram;
815 unsigned char *ubuf = (unsigned char *)buf;
816 int offset=0;
818 /* put in the header */
819 ubuf[0] = dgram->header.msg_type;
820 ubuf[1] = (((int)dgram->header.flags.node_type)<<2);
821 if (dgram->header.flags.more)
822 ubuf[1] |= 1;
823 if (dgram->header.flags.first)
824 ubuf[1] |= 2;
825 RSSVAL(ubuf,2,dgram->header.dgm_id);
826 putip(ubuf+4,(char *)&dgram->header.source_ip);
827 RSSVAL(ubuf,8,dgram->header.source_port);
828 RSSVAL(ubuf,12,dgram->header.packet_offset);
830 offset = 14;
832 if (dgram->header.msg_type == 0x10 ||
833 dgram->header.msg_type == 0x11 ||
834 dgram->header.msg_type == 0x12) {
835 offset += put_nmb_name((char *)ubuf,offset,&dgram->source_name);
836 offset += put_nmb_name((char *)ubuf,offset,&dgram->dest_name);
839 memcpy(ubuf+offset,dgram->data,dgram->datasize);
840 offset += dgram->datasize;
842 /* automatically set the dgm_length
843 * NOTE: RFC1002 says the dgm_length does *not*
844 * include the fourteen-byte header. crh
846 dgram->header.dgm_length = (offset - 14);
847 RSSVAL(ubuf,10,dgram->header.dgm_length);
849 return(offset);
852 /*******************************************************************
853 Build a nmb name
854 *******************************************************************/
856 void make_nmb_name( struct nmb_name *n, const char *name, int type)
858 fstring unix_name;
859 memset( (char *)n, '\0', sizeof(struct nmb_name) );
860 fstrcpy(unix_name, name);
861 strupper_m(unix_name);
862 push_ascii(n->name, unix_name, sizeof(n->name), STR_TERMINATE);
863 n->name_type = (unsigned int)type & 0xFF;
864 push_ascii(n->scope, global_scope(), 64, STR_TERMINATE);
867 /*******************************************************************
868 Compare two nmb names
869 ******************************************************************/
871 BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2)
873 return ((n1->name_type == n2->name_type) &&
874 strequal(n1->name ,n2->name ) &&
875 strequal(n1->scope,n2->scope));
878 /*******************************************************************
879 Build a nmb packet ready for sending.
881 XXXX this currently relies on not being passed something that expands
882 to a packet too big for the buffer. Eventually this should be
883 changed to set the trunc bit so the receiver can request the rest
884 via tcp (when that becomes supported)
885 ******************************************************************/
887 static int build_nmb(char *buf,struct packet_struct *p)
889 struct nmb_packet *nmb = &p->packet.nmb;
890 unsigned char *ubuf = (unsigned char *)buf;
891 int offset=0;
893 /* put in the header */
894 RSSVAL(ubuf,offset,nmb->header.name_trn_id);
895 ubuf[offset+2] = (nmb->header.opcode & 0xF) << 3;
896 if (nmb->header.response)
897 ubuf[offset+2] |= (1<<7);
898 if (nmb->header.nm_flags.authoritative &&
899 nmb->header.response)
900 ubuf[offset+2] |= 0x4;
901 if (nmb->header.nm_flags.trunc)
902 ubuf[offset+2] |= 0x2;
903 if (nmb->header.nm_flags.recursion_desired)
904 ubuf[offset+2] |= 0x1;
905 if (nmb->header.nm_flags.recursion_available &&
906 nmb->header.response)
907 ubuf[offset+3] |= 0x80;
908 if (nmb->header.nm_flags.bcast)
909 ubuf[offset+3] |= 0x10;
910 ubuf[offset+3] |= (nmb->header.rcode & 0xF);
912 RSSVAL(ubuf,offset+4,nmb->header.qdcount);
913 RSSVAL(ubuf,offset+6,nmb->header.ancount);
914 RSSVAL(ubuf,offset+8,nmb->header.nscount);
915 RSSVAL(ubuf,offset+10,nmb->header.arcount);
917 offset += 12;
918 if (nmb->header.qdcount) {
919 /* XXXX this doesn't handle a qdcount of > 1 */
920 offset += put_nmb_name((char *)ubuf,offset,&nmb->question.question_name);
921 RSSVAL(ubuf,offset,nmb->question.question_type);
922 RSSVAL(ubuf,offset+2,nmb->question.question_class);
923 offset += 4;
926 if (nmb->header.ancount)
927 offset += put_res_rec((char *)ubuf,offset,nmb->answers,
928 nmb->header.ancount);
930 if (nmb->header.nscount)
931 offset += put_res_rec((char *)ubuf,offset,nmb->nsrecs,
932 nmb->header.nscount);
935 * The spec says we must put compressed name pointers
936 * in the following outgoing packets :
937 * NAME_REGISTRATION_REQUEST, NAME_REFRESH_REQUEST,
938 * NAME_RELEASE_REQUEST.
941 if((nmb->header.response == False) &&
942 ((nmb->header.opcode == NMB_NAME_REG_OPCODE) ||
943 (nmb->header.opcode == NMB_NAME_RELEASE_OPCODE) ||
944 (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_8) ||
945 (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_9) ||
946 (nmb->header.opcode == NMB_NAME_MULTIHOMED_REG_OPCODE)) &&
947 (nmb->header.arcount == 1)) {
949 offset += put_compressed_name_ptr(ubuf,offset,nmb->additional,12);
951 } else if (nmb->header.arcount) {
952 offset += put_res_rec((char *)ubuf,offset,nmb->additional,
953 nmb->header.arcount);
955 return(offset);
958 /*******************************************************************
959 Linearise a packet.
960 ******************************************************************/
962 int build_packet(char *buf, struct packet_struct *p)
964 int len = 0;
966 switch (p->packet_type) {
967 case NMB_PACKET:
968 len = build_nmb(buf,p);
969 break;
971 case DGRAM_PACKET:
972 len = build_dgram(buf,p);
973 break;
976 return len;
979 /*******************************************************************
980 Send a packet_struct.
981 ******************************************************************/
983 BOOL send_packet(struct packet_struct *p)
985 char buf[1024];
986 int len=0;
988 memset(buf,'\0',sizeof(buf));
990 len = build_packet(buf, p);
992 if (!len)
993 return(False);
995 return(send_udp(p->fd,buf,len,p->ip,p->port));
998 /****************************************************************************
999 Receive a packet with timeout on a open UDP filedescriptor.
1000 The timeout is in milliseconds
1001 ***************************************************************************/
1003 struct packet_struct *receive_packet(int fd,enum packet_type type,int t)
1005 fd_set fds;
1006 struct timeval timeout;
1007 int ret;
1009 FD_ZERO(&fds);
1010 FD_SET(fd,&fds);
1011 timeout.tv_sec = t/1000;
1012 timeout.tv_usec = 1000*(t%1000);
1014 if ((ret = sys_select_intr(fd+1,&fds,NULL,NULL,&timeout)) == -1) {
1015 /* errno should be EBADF or EINVAL. */
1016 DEBUG(0,("select returned -1, errno = %s (%d)\n", strerror(errno), errno));
1017 return NULL;
1020 if (ret == 0) /* timeout */
1021 return NULL;
1023 if (FD_ISSET(fd,&fds))
1024 return(read_packet(fd,type));
1026 return(NULL);
1029 /****************************************************************************
1030 Receive a UDP/137 packet either via UDP or from the unexpected packet
1031 queue. The packet must be a reply packet and have the specified trn_id.
1032 The timeout is in milliseconds.
1033 ***************************************************************************/
1035 struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id)
1037 struct packet_struct *p;
1039 p = receive_packet(fd, NMB_PACKET, t);
1041 if (p && p->packet.nmb.header.response &&
1042 p->packet.nmb.header.name_trn_id == trn_id) {
1043 return p;
1045 if (p)
1046 free_packet(p);
1048 /* try the unexpected packet queue */
1049 return receive_unexpected(NMB_PACKET, trn_id, NULL);
1052 /****************************************************************************
1053 Receive a UDP/138 packet either via UDP or from the unexpected packet
1054 queue. The packet must be a reply packet and have the specified mailslot name
1055 The timeout is in milliseconds.
1056 ***************************************************************************/
1058 struct packet_struct *receive_dgram_packet(int fd, int t, const char *mailslot_name)
1060 struct packet_struct *p;
1062 p = receive_packet(fd, DGRAM_PACKET, t);
1064 if (p && match_mailslot_name(p, mailslot_name)) {
1065 return p;
1067 if (p)
1068 free_packet(p);
1070 /* try the unexpected packet queue */
1071 return receive_unexpected(DGRAM_PACKET, 0, mailslot_name);
1074 /****************************************************************************
1075 See if a datagram has the right mailslot name.
1076 ***************************************************************************/
1078 BOOL match_mailslot_name(struct packet_struct *p, const char *mailslot_name)
1080 struct dgram_packet *dgram = &p->packet.dgram;
1081 char *buf;
1083 buf = &dgram->data[0];
1084 buf -= 4;
1086 buf = smb_buf(buf);
1088 if (memcmp(buf, mailslot_name, strlen(mailslot_name)+1) == 0) {
1089 return True;
1092 return False;
1095 /****************************************************************************
1096 Return the number of bits that match between two 4 character buffers
1097 ***************************************************************************/
1099 int matching_quad_bits(unsigned char *p1, unsigned char *p2)
1101 int i, j, ret = 0;
1102 for (i=0; i<4; i++) {
1103 if (p1[i] != p2[i])
1104 break;
1105 ret += 8;
1108 if (i==4)
1109 return ret;
1111 for (j=0; j<8; j++) {
1112 if ((p1[i] & (1<<(7-j))) != (p2[i] & (1<<(7-j))))
1113 break;
1114 ret++;
1117 return ret;
1120 static unsigned char sort_ip[4];
1122 /****************************************************************************
1123 Compare two query reply records.
1124 ***************************************************************************/
1126 static int name_query_comp(unsigned char *p1, unsigned char *p2)
1128 return matching_quad_bits(p2+2, sort_ip) - matching_quad_bits(p1+2, sort_ip);
1131 /****************************************************************************
1132 Sort a set of 6 byte name query response records so that the IPs that
1133 have the most leading bits in common with the specified address come first.
1134 ***************************************************************************/
1136 void sort_query_replies(char *data, int n, struct in_addr ip)
1138 if (n <= 1)
1139 return;
1141 putip(sort_ip, (char *)&ip);
1143 qsort(data, n, 6, QSORT_CAST name_query_comp);
1146 #define TRUNCATE_NETBIOS_NAME 1
1148 /*******************************************************************
1149 Convert, possibly using a stupid microsoft-ism which has destroyed
1150 the transport independence of netbios (for CIFS vendors that usually
1151 use the Win95-type methods, not for NT to NT communication, which uses
1152 DCE/RPC and therefore full-length unicode strings...) a dns name into
1153 a netbios name.
1155 The netbios name (NOT necessarily null-terminated) is truncated to 15
1156 characters.
1158 ******************************************************************/
1160 char *dns_to_netbios_name(const char *dns_name)
1162 static nstring netbios_name;
1163 int i;
1164 StrnCpy(netbios_name, dns_name, MAX_NETBIOSNAME_LEN-1);
1165 netbios_name[15] = 0;
1167 #ifdef TRUNCATE_NETBIOS_NAME
1168 /* ok. this is because of a stupid microsoft-ism. if the called host
1169 name contains a '.', microsoft clients expect you to truncate the
1170 netbios name up to and including the '.' this even applies, by
1171 mistake, to workgroup (domain) names, which is _really_ daft.
1173 for (i = 0; i >= 15; i--) {
1174 if (netbios_name[i] == '.') {
1175 netbios_name[i] = 0;
1176 break;
1179 #endif /* TRUNCATE_NETBIOS_NAME */
1181 return netbios_name;
1184 /****************************************************************************
1185 Interpret the weird netbios "name" into a unix fstring. Return the name type.
1186 ****************************************************************************/
1188 static int name_interpret(char *in, fstring name)
1190 int ret;
1191 int len = (*in++) / 2;
1192 fstring out_string;
1193 char *out = out_string;
1195 *out=0;
1197 if (len > 30 || len<1)
1198 return(0);
1200 while (len--) {
1201 if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
1202 *out = 0;
1203 return(0);
1205 *out = ((in[0]-'A')<<4) + (in[1]-'A');
1206 in += 2;
1207 out++;
1209 ret = out[-1];
1210 out[-1] = 0;
1212 #ifdef NETBIOS_SCOPE
1213 /* Handle any scope names */
1214 while(*in) {
1215 *out++ = '.'; /* Scope names are separated by periods */
1216 len = *(unsigned char *)in++;
1217 StrnCpy(out, in, len);
1218 out += len;
1219 *out=0;
1220 in += len;
1222 #endif
1223 pull_ascii_fstring(name, out_string);
1225 return(ret);
1228 /****************************************************************************
1229 Mangle a name into netbios format.
1230 Note: <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
1231 ****************************************************************************/
1233 int name_mangle( char *In, char *Out, char name_type )
1235 int i;
1236 int len;
1237 nstring buf;
1238 char *p = Out;
1240 /* Safely copy the input string, In, into buf[]. */
1241 if (strcmp(In,"*") == 0)
1242 put_name(buf, "*", '\0', 0x00);
1243 else {
1244 /* We use an fstring here as mb dos names can expend x3 when
1245 going to utf8. */
1246 fstring buf_unix;
1247 nstring buf_dos;
1249 pull_ascii_fstring(buf_unix, In);
1250 strupper_m(buf_unix);
1252 push_ascii_nstring(buf_dos, buf_unix);
1253 put_name(buf, buf_dos, ' ', name_type);
1256 /* Place the length of the first field into the output buffer. */
1257 p[0] = 32;
1258 p++;
1260 /* Now convert the name to the rfc1001/1002 format. */
1261 for( i = 0; i < MAX_NETBIOSNAME_LEN; i++ ) {
1262 p[i*2] = ( (buf[i] >> 4) & 0x000F ) + 'A';
1263 p[(i*2)+1] = (buf[i] & 0x000F) + 'A';
1265 p += 32;
1266 p[0] = '\0';
1268 /* Add the scope string. */
1269 for( i = 0, len = 0; *(global_scope()) != '\0'; i++, len++ ) {
1270 switch( (global_scope())[i] ) {
1271 case '\0':
1272 p[0] = len;
1273 if( len > 0 )
1274 p[len+1] = 0;
1275 return( name_len(Out) );
1276 case '.':
1277 p[0] = len;
1278 p += (len + 1);
1279 len = -1;
1280 break;
1281 default:
1282 p[len+1] = (global_scope())[i];
1283 break;
1287 return( name_len(Out) );
1290 /****************************************************************************
1291 Find a pointer to a netbios name.
1292 ****************************************************************************/
1294 static char *name_ptr(char *buf,int ofs)
1296 unsigned char c = *(unsigned char *)(buf+ofs);
1298 if ((c & 0xC0) == 0xC0) {
1299 uint16 l = RSVAL(buf, ofs) & 0x3FFF;
1300 DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
1301 return(buf + l);
1302 } else {
1303 return(buf+ofs);
1307 /****************************************************************************
1308 Extract a netbios name from a buf (into a unix string) return name type.
1309 ****************************************************************************/
1311 int name_extract(char *buf,int ofs, fstring name)
1313 char *p = name_ptr(buf,ofs);
1314 int d = PTR_DIFF(p,buf+ofs);
1316 name[0] = '\0';
1317 if (d < -50 || d > 50)
1318 return(0);
1319 return(name_interpret(p,name));
1322 /****************************************************************************
1323 Return the total storage length of a mangled name.
1324 ****************************************************************************/
1326 int name_len(char *s1)
1328 /* NOTE: this argument _must_ be unsigned */
1329 unsigned char *s = (unsigned char *)s1;
1330 int len;
1332 /* If the two high bits of the byte are set, return 2. */
1333 if (0xC0 == (*s & 0xC0))
1334 return(2);
1336 /* Add up the length bytes. */
1337 for (len = 1; (*s); s += (*s) + 1) {
1338 len += *s + 1;
1339 SMB_ASSERT(len < 80);
1342 return(len);