2 Unix SMB/Netbios implementation.
4 NBT netbios library routines
5 Copyright (C) Andrew Tridgell 1994-1995
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 2 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, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 extern struct in_addr myip;
28 extern int DEBUGLEVEL;
30 int num_good_sends = 0;
31 int num_good_receives = 0;
33 extern pstring myname;
34 extern struct in_addr ipzero;
37 /****************************************************************************
38 print out a res_rec structure
39 ****************************************************************************/
40 static void debug_nmb_res_rec(struct res_rec *res, char *hdr)
44 DEBUG(4,(" %s: nmb_name=%s rr_type=%d rr_class=%d ttl=%d\n",
46 namestr(&res->rr_name),
51 if (res->rdlength == 0 || res->rdata == NULL) return;
53 for (i = 0; i < res->rdlength; i+= 16)
55 DEBUG(4, (" %s %3x char ", hdr, i));
57 for (j = 0; j < 16; j++)
59 unsigned char x = res->rdata[i+j];
60 if (x < 32 || x > 127) x = '.';
62 if (i+j >= res->rdlength) break;
66 DEBUG(4, (" hex ", i));
68 for (j = 0; j < 16; j++)
70 if (i+j >= res->rdlength) break;
71 DEBUG(4, ("%02X", (unsigned char)res->rdata[i+j]));
78 /****************************************************************************
80 ****************************************************************************/
81 void debug_nmb_packet(struct packet_struct *p)
83 struct nmb_packet *nmb = &p->packet.nmb;
85 DEBUG(4,("nmb packet from %s header: id=%d opcode=%d response=%s\n",
87 nmb->header.name_trn_id,nmb->header.opcode,BOOLSTR(nmb->header.response)));
88 DEBUG(4,(" header: flags: bcast=%s rec_avail=%s rec_des=%s trunc=%s auth=%s\n",
89 BOOLSTR(nmb->header.nm_flags.bcast),
90 BOOLSTR(nmb->header.nm_flags.recursion_available),
91 BOOLSTR(nmb->header.nm_flags.recursion_desired),
92 BOOLSTR(nmb->header.nm_flags.trunc),
93 BOOLSTR(nmb->header.nm_flags.authoritative)));
94 DEBUG(4,(" header: rcode=%d qdcount=%d ancount=%d nscount=%d arcount=%d\n",
99 nmb->header.arcount));
101 if (nmb->header.qdcount)
103 DEBUG(4,(" question: q_name=%s q_type=%d q_class=%d\n",
104 namestr(&nmb->question.question_name),
105 nmb->question.question_type,
106 nmb->question.question_class));
109 if (nmb->answers && nmb->header.ancount)
111 debug_nmb_res_rec(nmb->answers,"answers");
113 if (nmb->nsrecs && nmb->header.nscount)
115 debug_nmb_res_rec(nmb->nsrecs,"nsrecs");
117 if (nmb->additional && nmb->header.arcount)
119 debug_nmb_res_rec(nmb->additional,"additional");
123 /*******************************************************************
124 handle "compressed" name pointers
125 ******************************************************************/
126 static BOOL handle_name_ptrs(unsigned char *ubuf,int *offset,int length,
127 BOOL *got_pointer,int *ret)
131 while ((ubuf[*offset] & 0xC0) == 0xC0) {
132 if (!*got_pointer) (*ret) += 2;
134 (*offset) = ((ubuf[*offset] & ~0xC0)<<8) | ubuf[(*offset)+1];
135 if (loop_count++ == 10 || (*offset) < 0 || (*offset)>(length-2)) {
142 /*******************************************************************
143 parse a nmb name from "compressed" format to something readable
144 return the space taken by the name, or 0 if the name is invalid
145 ******************************************************************/
146 static int parse_nmb_name(char *inbuf,int offset,int length, struct nmb_name *name)
149 unsigned char *ubuf = (unsigned char *)inbuf;
151 BOOL got_pointer=False;
153 if (length - offset < 2) return(0);
155 /* handle initial name pointers */
156 if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) return(0);
161 if ((m & 0xC0) || offset+m+2 > length) return(0);
163 bzero((char *)name,sizeof(*name));
165 /* the "compressed" part */
166 if (!got_pointer) ret += m + 2;
170 c1 = ubuf[offset++]-'A';
171 c2 = ubuf[offset++]-'A';
172 if ((c1 & 0xF0) || (c2 & 0xF0)) return(0);
173 name->name[n++] = (c1<<4) | c2;
179 /* parse out the name type,
180 its always in the 16th byte of the name */
181 name->name_type = name->name[15];
183 /* remove trailing spaces */
186 while (n && name->name[n]==' ') name->name[n--] = 0;
189 /* now the domain parts (if any) */
191 while ((m=ubuf[offset])) {
192 /* we can have pointers within the domain part as well */
193 if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) return(0);
195 if (!got_pointer) ret += m+1;
196 if (n) name->scope[n++] = '.';
197 if (m+2+offset>length || n+m+1>sizeof(name->scope)) return(0);
199 while (m--) name->scope[n++] = (char)ubuf[offset++];
201 name->scope[n++] = 0;
207 /*******************************************************************
208 put a compressed nmb name into a buffer. return the length of the
211 compressed names are really weird. The "compression" doubles the
212 size. The idea is that it also means that compressed names conform
213 to the doman name system. See RFC1002.
214 ******************************************************************/
215 static int put_nmb_name(char *buf,int offset,struct nmb_name *name)
221 if (name->name[0] == '*') {
222 /* special case for wildcard name */
226 sprintf(buf1,"%-15.15s%c",name->name,name->name_type);
234 buf[offset+1+2*m] = 'A' + ((buf1[m]>>4)&0xF);
235 buf[offset+2+2*m] = 'A' + (buf1[m]&0xF);
241 if (name->scope[0]) {
242 /* XXXX this scope handling needs testing */
243 ret += strlen(name->scope) + 1;
244 strcpy(&buf[offset+1],name->scope);
247 while ((p = strchr(p,'.'))) {
248 buf[offset] = PTR_DIFF(p,&buf[offset]);
249 offset += buf[offset];
252 buf[offset] = strlen(&buf[offset+1]);
258 /*******************************************************************
259 useful for debugging messages
260 ******************************************************************/
261 char *namestr(struct nmb_name *n)
264 static fstring ret[4];
268 sprintf(p,"%s(%x)",n->name,n->name_type);
270 sprintf(p,"%s(%x).%s",n->name,n->name_type,n->scope);
276 /*******************************************************************
277 allocate and parse some resource records
278 ******************************************************************/
279 static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length,
280 struct res_rec **recs, int count)
283 *recs = (struct res_rec *)malloc(sizeof(**recs)*count);
284 if (!*recs) return(False);
286 bzero(*recs,sizeof(**recs)*count);
288 for (i=0;i<count;i++) {
289 int l = parse_nmb_name(inbuf,*offset,length,&(*recs)[i].rr_name);
291 if (!l || (*offset)+10 > length) {
295 (*recs)[i].rr_type = RSVAL(inbuf,(*offset));
296 (*recs)[i].rr_class = RSVAL(inbuf,(*offset)+2);
297 (*recs)[i].ttl = RIVAL(inbuf,(*offset)+4);
298 (*recs)[i].rdlength = RSVAL(inbuf,(*offset)+8);
300 if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) ||
301 (*offset)+(*recs)[i].rdlength > length) {
305 memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength);
306 (*offset) += (*recs)[i].rdlength;
311 /*******************************************************************
312 put a resource record into a packet
313 ******************************************************************/
314 static int put_res_rec(char *buf,int offset,struct res_rec *recs,int count)
319 for (i=0;i<count;i++) {
320 int l = put_nmb_name(buf,offset,&recs[i].rr_name);
323 RSSVAL(buf,offset,recs[i].rr_type);
324 RSSVAL(buf,offset+2,recs[i].rr_class);
325 RSIVAL(buf,offset+4,recs[i].ttl);
326 RSSVAL(buf,offset+8,recs[i].rdlength);
327 memcpy(buf+offset+10,recs[i].rdata,recs[i].rdlength);
328 offset += 10+recs[i].rdlength;
329 ret += 10+recs[i].rdlength;
335 /*******************************************************************
336 parse a dgram packet. Return False if the packet can't be parsed
337 or is invalid for some reason, True otherwise
339 this is documented in section 4.4.1 of RFC1002
340 ******************************************************************/
341 static BOOL parse_dgram(char *inbuf,int length,struct dgram_packet *dgram)
346 bzero((char *)dgram,sizeof(*dgram));
348 if (length < 14) return(False);
350 dgram->header.msg_type = CVAL(inbuf,0);
351 flags = CVAL(inbuf,1);
352 dgram->header.flags.node_type = (enum node_type)((flags>>2)&3);
353 if (flags & 1) dgram->header.flags.more = True;
354 if (flags & 2) dgram->header.flags.first = True;
355 dgram->header.dgm_id = RSVAL(inbuf,2);
356 putip((char *)&dgram->header.source_ip,inbuf+4);
357 dgram->header.source_port = RSVAL(inbuf,8);
358 dgram->header.dgm_length = RSVAL(inbuf,10);
359 dgram->header.packet_offset = RSVAL(inbuf,12);
363 if (dgram->header.msg_type == 0x10 ||
364 dgram->header.msg_type == 0x11 ||
365 dgram->header.msg_type == 0x12) {
366 offset += parse_nmb_name(inbuf,offset,length,&dgram->source_name);
367 offset += parse_nmb_name(inbuf,offset,length,&dgram->dest_name);
370 if (offset >= length || (length-offset > sizeof(dgram->data)))
373 dgram->datasize = length-offset;
374 memcpy(dgram->data,inbuf+offset,dgram->datasize);
380 /*******************************************************************
381 parse a nmb packet. Return False if the packet can't be parsed
382 or is invalid for some reason, True otherwise
383 ******************************************************************/
384 static BOOL parse_nmb(char *inbuf,int length,struct nmb_packet *nmb)
388 bzero((char *)nmb,sizeof(*nmb));
390 if (length < 12) return(False);
392 /* parse the header */
393 nmb->header.name_trn_id = RSVAL(inbuf,0);
394 nmb->header.opcode = (CVAL(inbuf,2) >> 3) & 0xF;
395 nmb->header.response = ((CVAL(inbuf,2)>>7)&1)?True:False;
396 nm_flags = ((CVAL(inbuf,2) & 0x7) << 4) + (CVAL(inbuf,3)>>4);
397 nmb->header.nm_flags.bcast = (nm_flags&1)?True:False;
398 nmb->header.nm_flags.recursion_available = (nm_flags&8)?True:False;
399 nmb->header.nm_flags.recursion_desired = (nm_flags&0x10)?True:False;
400 nmb->header.nm_flags.trunc = (nm_flags&0x20)?True:False;
401 nmb->header.nm_flags.authoritative = (nm_flags&0x40)?True:False;
402 nmb->header.rcode = CVAL(inbuf,3) & 0xF;
403 nmb->header.qdcount = RSVAL(inbuf,4);
404 nmb->header.ancount = RSVAL(inbuf,6);
405 nmb->header.nscount = RSVAL(inbuf,8);
406 nmb->header.arcount = RSVAL(inbuf,10);
408 if (nmb->header.qdcount) {
409 offset = parse_nmb_name(inbuf,12,length,&nmb->question.question_name);
410 if (!offset) return(False);
412 if (length - (12+offset) < 4) return(False);
413 nmb->question.question_type = RSVAL(inbuf,12+offset);
414 nmb->question.question_class = RSVAL(inbuf,12+offset+2);
421 /* and any resource records */
422 if (nmb->header.ancount &&
423 !parse_alloc_res_rec(inbuf,&offset,length,&nmb->answers,
424 nmb->header.ancount))
427 if (nmb->header.nscount &&
428 !parse_alloc_res_rec(inbuf,&offset,length,&nmb->nsrecs,
429 nmb->header.nscount))
432 if (nmb->header.arcount &&
433 !parse_alloc_res_rec(inbuf,&offset,length,&nmb->additional,
434 nmb->header.arcount))
440 /*******************************************************************
441 free up any resources associated with an nmb packet
442 ******************************************************************/
443 void free_nmb_packet(struct nmb_packet *nmb)
445 if (nmb->answers) free(nmb->answers);
446 if (nmb->nsrecs) free(nmb->nsrecs);
447 if (nmb->additional) free(nmb->additional);
450 /*******************************************************************
451 free up any resources associated with a packet
452 ******************************************************************/
453 void free_packet(struct packet_struct *packet)
455 if (packet->packet_type == NMB_PACKET)
456 free_nmb_packet(&packet->packet.nmb);
460 /*******************************************************************
461 read a packet from a socket and parse it, returning a packet ready
462 to be used or put on the queue. This assumes a UDP socket
463 ******************************************************************/
464 struct packet_struct *read_packet(int fd,enum packet_type packet_type)
466 extern struct in_addr lastip;
468 struct packet_struct *packet;
469 char buf[MAX_DGRAM_SIZE];
473 length = read_udp_socket(fd,buf,sizeof(buf));
474 if (length < MIN_DGRAM_SIZE) return(NULL);
476 packet = (struct packet_struct *)malloc(sizeof(*packet));
477 if (!packet) return(NULL);
482 packet->port = lastport;
484 packet->timestamp = time(NULL);
485 packet->packet_type = packet_type;
489 ok = parse_nmb(buf,length,&packet->packet.nmb);
493 ok = parse_dgram(buf,length,&packet->packet.dgram);
503 DEBUG(4,("%s received a packet of len %d from (%s) port %d\n",
504 timestring(),length,inet_ntoa(packet->ip),packet->port));
510 /*******************************************************************
511 send a udp packet on a already open socket
512 ******************************************************************/
513 static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port)
516 struct sockaddr_in sock_out;
518 /* set the address and port */
519 bzero((char *)&sock_out,sizeof(sock_out));
520 putip((char *)&sock_out.sin_addr,(char *)&ip);
521 sock_out.sin_port = htons( port );
522 sock_out.sin_family = AF_INET;
524 DEBUG(4,("%s sending a packet of len %d to (%s) on port %d\n",
525 timestring(),len,inet_ntoa(ip),port));
527 ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out,
528 sizeof(sock_out)) >= 0);
531 DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n",
532 inet_ntoa(ip),port,strerror(errno)));
540 /*******************************************************************
541 build a dgram packet ready for sending
543 XXXX This currently doesn't handle packets too big for one
544 datagram. It should split them and use the packet_offset, more and
545 first flags to handle the fragmentation. Yuck.
546 ******************************************************************/
547 static int build_dgram(char *buf,struct packet_struct *p)
549 struct dgram_packet *dgram = &p->packet.dgram;
550 unsigned char *ubuf = (unsigned char *)buf;
553 /* put in the header */
554 ubuf[0] = dgram->header.msg_type;
555 ubuf[1] = (((int)dgram->header.flags.node_type)<<2);
556 if (dgram->header.flags.more) ubuf[1] |= 1;
557 if (dgram->header.flags.first) ubuf[1] |= 2;
558 RSSVAL(ubuf,2,dgram->header.dgm_id);
559 putip(ubuf+4,(char *)&dgram->header.source_ip);
560 RSSVAL(ubuf,8,dgram->header.source_port);
561 RSSVAL(ubuf,12,dgram->header.packet_offset);
565 if (dgram->header.msg_type == 0x10 ||
566 dgram->header.msg_type == 0x11 ||
567 dgram->header.msg_type == 0x12) {
568 offset += put_nmb_name((char *)ubuf,offset,&dgram->source_name);
569 offset += put_nmb_name((char *)ubuf,offset,&dgram->dest_name);
572 memcpy(ubuf+offset,dgram->data,dgram->datasize);
573 offset += dgram->datasize;
575 /* automatically set the dgm_length */
576 dgram->header.dgm_length = offset;
577 RSSVAL(ubuf,10,dgram->header.dgm_length);
582 /*******************************************************************
584 ******************************************************************/
585 void make_nmb_name(struct nmb_name *n,char *name,int type,char *this_scope)
587 strcpy(n->name,name);
590 strcpy(n->scope,this_scope);
594 /*******************************************************************
595 build a nmb packet ready for sending
597 XXXX this currently relies on not being passed something that expands
598 to a packet too big for the buffer. Eventually this should be
599 changed to set the trunc bit so the receiver can request the rest
600 via tcp (when that becomes supported)
601 ******************************************************************/
602 static int build_nmb(char *buf,struct packet_struct *p)
604 struct nmb_packet *nmb = &p->packet.nmb;
605 unsigned char *ubuf = (unsigned char *)buf;
608 /* put in the header */
609 RSSVAL(ubuf,offset,nmb->header.name_trn_id);
610 ubuf[offset+2] = (nmb->header.opcode & 0xF) << 3;
611 if (nmb->header.response) ubuf[offset+2] |= (1<<7);
612 if (nmb->header.nm_flags.authoritative) ubuf[offset+2] |= 0x4;
613 if (nmb->header.nm_flags.trunc) ubuf[offset+2] |= 0x2;
614 if (nmb->header.nm_flags.recursion_desired) ubuf[offset+2] |= 0x1;
615 if (nmb->header.nm_flags.recursion_available) ubuf[offset+3] |= 0x80;
616 if (nmb->header.nm_flags.bcast) ubuf[offset+3] |= 0x10;
617 ubuf[offset+3] |= (nmb->header.rcode & 0xF);
619 RSSVAL(ubuf,offset+4,nmb->header.qdcount);
620 RSSVAL(ubuf,offset+6,nmb->header.ancount);
621 RSSVAL(ubuf,offset+8,nmb->header.nscount);
622 RSSVAL(ubuf,offset+10,nmb->header.arcount);
625 if (nmb->header.qdcount) {
626 /* XXXX this doesn't handle a qdcount of > 1 */
627 offset += put_nmb_name((char *)ubuf,offset,&nmb->question.question_name);
628 RSSVAL(ubuf,offset,nmb->question.question_type);
629 RSSVAL(ubuf,offset+2,nmb->question.question_class);
633 if (nmb->header.ancount)
634 offset += put_res_rec((char *)ubuf,offset,nmb->answers,
635 nmb->header.ancount);
637 if (nmb->header.nscount)
638 offset += put_res_rec((char *)ubuf,offset,nmb->nsrecs,
639 nmb->header.nscount);
641 if (nmb->header.arcount)
642 offset += put_res_rec((char *)ubuf,offset,nmb->additional,
643 nmb->header.arcount);
649 /*******************************************************************
651 ******************************************************************/
652 BOOL send_packet(struct packet_struct *p)
657 bzero(buf,sizeof(buf));
659 switch (p->packet_type)
662 len = build_nmb(buf,p);
666 len = build_dgram(buf,p);
670 if (!len) return(False);
672 return(send_udp(p->fd,buf,len,p->ip,p->port));
675 /****************************************************************************
676 receive a packet with timeout on a open UDP filedescriptor
677 The timeout is in milliseconds
678 ***************************************************************************/
679 struct packet_struct *receive_packet(int fd,enum packet_type type,int t)
682 struct timeval timeout;
686 timeout.tv_sec = t/1000;
687 timeout.tv_usec = 1000*(t%1000);
689 sys_select(&fds,&timeout);
691 if (FD_ISSET(fd,&fds))
692 return(read_packet(fd,type));