2 Unix SMB/Netbios implementation.
4 NBT netbios library routines
5 Copyright (C) Andrew Tridgell 1994-1997
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.
25 extern int DEBUGLEVEL
;
27 int num_good_sends
= 0;
28 int num_good_receives
= 0;
30 extern pstring myname
;
31 extern struct in_addr ipzero
;
33 static struct opcode_names
{
34 const char *nmb_opcode_name
;
36 } nmb_header_opcode_names
[] = {
45 /****************************************************************************
46 * Lookup a nmb opcode name.
47 ****************************************************************************/
49 const char *lookup_opcode_name( int opcode
)
51 struct opcode_names
*op_namep
;
54 for(i
= 0; nmb_header_opcode_names
[i
].nmb_opcode_name
!= 0; i
++) {
55 op_namep
= &nmb_header_opcode_names
[i
];
56 if(opcode
== op_namep
->opcode
)
57 return op_namep
->nmb_opcode_name
;
59 return "<unknown opcode>";
62 /****************************************************************************
63 print out a res_rec structure
64 ****************************************************************************/
65 static void debug_nmb_res_rec(struct res_rec
*res
, char *hdr
)
69 DEBUG(4,(" %s: nmb_name=%s rr_type=%d rr_class=%d ttl=%d\n",
71 namestr(&res
->rr_name
),
76 if (res
->rdlength
== 0 || res
->rdata
== NULL
) return;
78 for (i
= 0; i
< res
->rdlength
; i
+= 16)
80 DEBUG(4, (" %s %3x char ", hdr
, i
));
82 for (j
= 0; j
< 16; j
++)
84 unsigned char x
= res
->rdata
[i
+j
];
85 if (x
< 32 || x
> 127) x
= '.';
87 if (i
+j
>= res
->rdlength
) break;
91 DEBUG(4, (" hex ", i
));
93 for (j
= 0; j
< 16; j
++)
95 if (i
+j
>= res
->rdlength
) break;
96 DEBUG(4, ("%02X", (unsigned char)res
->rdata
[i
+j
]));
103 /****************************************************************************
105 ****************************************************************************/
106 void debug_nmb_packet(struct packet_struct
*p
)
108 struct nmb_packet
*nmb
= &p
->packet
.nmb
;
110 DEBUG(4,("nmb packet from %s header: id=%d opcode=%s(%d) response=%s\n",
112 nmb
->header
.name_trn_id
,
113 lookup_opcode_name(nmb
->header
.opcode
),
114 nmb
->header
.opcode
,BOOLSTR(nmb
->header
.response
)));
115 DEBUG(4,(" header: flags: bcast=%s rec_avail=%s rec_des=%s trunc=%s auth=%s\n",
116 BOOLSTR(nmb
->header
.nm_flags
.bcast
),
117 BOOLSTR(nmb
->header
.nm_flags
.recursion_available
),
118 BOOLSTR(nmb
->header
.nm_flags
.recursion_desired
),
119 BOOLSTR(nmb
->header
.nm_flags
.trunc
),
120 BOOLSTR(nmb
->header
.nm_flags
.authoritative
)));
121 DEBUG(4,(" header: rcode=%d qdcount=%d ancount=%d nscount=%d arcount=%d\n",
126 nmb
->header
.arcount
));
128 if (nmb
->header
.qdcount
)
130 DEBUG(4,(" question: q_name=%s q_type=%d q_class=%d\n",
131 namestr(&nmb
->question
.question_name
),
132 nmb
->question
.question_type
,
133 nmb
->question
.question_class
));
136 if (nmb
->answers
&& nmb
->header
.ancount
)
138 debug_nmb_res_rec(nmb
->answers
,"answers");
140 if (nmb
->nsrecs
&& nmb
->header
.nscount
)
142 debug_nmb_res_rec(nmb
->nsrecs
,"nsrecs");
144 if (nmb
->additional
&& nmb
->header
.arcount
)
146 debug_nmb_res_rec(nmb
->additional
,"additional");
150 /*******************************************************************
151 handle "compressed" name pointers
152 ******************************************************************/
153 static BOOL
handle_name_ptrs(unsigned char *ubuf
,int *offset
,int length
,
154 BOOL
*got_pointer
,int *ret
)
158 while ((ubuf
[*offset
] & 0xC0) == 0xC0) {
159 if (!*got_pointer
) (*ret
) += 2;
161 (*offset
) = ((ubuf
[*offset
] & ~0xC0)<<8) | ubuf
[(*offset
)+1];
162 if (loop_count
++ == 10 || (*offset
) < 0 || (*offset
)>(length
-2)) {
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 ******************************************************************/
173 static int parse_nmb_name(char *inbuf
,int offset
,int length
, struct nmb_name
*name
)
176 unsigned char *ubuf
= (unsigned char *)inbuf
;
178 BOOL got_pointer
=False
;
180 if (length
- offset
< 2) return(0);
182 /* handle initial name pointers */
183 if (!handle_name_ptrs(ubuf
,&offset
,length
,&got_pointer
,&ret
)) return(0);
188 if ((m
& 0xC0) || offset
+m
+2 > length
) return(0);
190 bzero((char *)name
,sizeof(*name
));
192 /* the "compressed" part */
193 if (!got_pointer
) ret
+= m
+ 2;
197 c1
= ubuf
[offset
++]-'A';
198 c2
= ubuf
[offset
++]-'A';
199 if ((c1
& 0xF0) || (c2
& 0xF0)) return(0);
200 name
->name
[n
++] = (c1
<<4) | c2
;
206 /* parse out the name type,
207 its always in the 16th byte of the name */
208 name
->name_type
= name
->name
[15];
210 /* remove trailing spaces */
213 while (n
&& name
->name
[n
]==' ') name
->name
[n
--] = 0;
216 /* now the domain parts (if any) */
218 while ((m
=ubuf
[offset
])) {
219 /* we can have pointers within the domain part as well */
220 if (!handle_name_ptrs(ubuf
,&offset
,length
,&got_pointer
,&ret
)) return(0);
222 if (!got_pointer
) ret
+= m
+1;
223 if (n
) name
->scope
[n
++] = '.';
224 if (m
+2+offset
>length
|| n
+m
+1>sizeof(name
->scope
)) return(0);
226 while (m
--) name
->scope
[n
++] = (char)ubuf
[offset
++];
228 name
->scope
[n
++] = 0;
234 /*******************************************************************
235 put a compressed nmb name into a buffer. return the length of the
238 compressed names are really weird. The "compression" doubles the
239 size. The idea is that it also means that compressed names conform
240 to the doman name system. See RFC1002.
241 ******************************************************************/
242 static int put_nmb_name(char *buf
,int offset
,struct nmb_name
*name
)
248 if (name
->name
[0] == '*') {
249 /* special case for wildcard name */
253 sprintf(buf1
,"%-15.15s%c",name
->name
,name
->name_type
);
261 buf
[offset
+1+2*m
] = 'A' + ((buf1
[m
]>>4)&0xF);
262 buf
[offset
+2+2*m
] = 'A' + (buf1
[m
]&0xF);
268 if (name
->scope
[0]) {
269 /* XXXX this scope handling needs testing */
270 ret
+= strlen(name
->scope
) + 1;
271 strcpy(&buf
[offset
+1],name
->scope
);
274 while ((p
= strchr(p
,'.'))) {
275 buf
[offset
] = PTR_DIFF(p
,&buf
[offset
]);
276 offset
+= buf
[offset
];
279 buf
[offset
] = strlen(&buf
[offset
+1]);
285 /*******************************************************************
286 useful for debugging messages
287 ******************************************************************/
288 char *namestr(struct nmb_name
*n
)
291 static fstring ret
[4];
295 sprintf(p
,"%s(%x)",n
->name
,n
->name_type
);
297 sprintf(p
,"%s(%x).%s",n
->name
,n
->name_type
,n
->scope
);
303 /*******************************************************************
304 allocate and parse some resource records
305 ******************************************************************/
306 static BOOL
parse_alloc_res_rec(char *inbuf
,int *offset
,int length
,
307 struct res_rec
**recs
, int count
)
310 *recs
= (struct res_rec
*)malloc(sizeof(**recs
)*count
);
311 if (!*recs
) return(False
);
313 bzero(*recs
,sizeof(**recs
)*count
);
315 for (i
=0;i
<count
;i
++) {
316 int l
= parse_nmb_name(inbuf
,*offset
,length
,&(*recs
)[i
].rr_name
);
318 if (!l
|| (*offset
)+10 > length
) {
322 (*recs
)[i
].rr_type
= RSVAL(inbuf
,(*offset
));
323 (*recs
)[i
].rr_class
= RSVAL(inbuf
,(*offset
)+2);
324 (*recs
)[i
].ttl
= RIVAL(inbuf
,(*offset
)+4);
325 (*recs
)[i
].rdlength
= RSVAL(inbuf
,(*offset
)+8);
327 if ((*recs
)[i
].rdlength
>sizeof((*recs
)[i
].rdata
) ||
328 (*offset
)+(*recs
)[i
].rdlength
> length
) {
332 memcpy((*recs
)[i
].rdata
,inbuf
+(*offset
),(*recs
)[i
].rdlength
);
333 (*offset
) += (*recs
)[i
].rdlength
;
338 /*******************************************************************
339 put a resource record into a packet
340 ******************************************************************/
341 static int put_res_rec(char *buf
,int offset
,struct res_rec
*recs
,int count
)
346 for (i
=0;i
<count
;i
++) {
347 int l
= put_nmb_name(buf
,offset
,&recs
[i
].rr_name
);
350 RSSVAL(buf
,offset
,recs
[i
].rr_type
);
351 RSSVAL(buf
,offset
+2,recs
[i
].rr_class
);
352 RSIVAL(buf
,offset
+4,recs
[i
].ttl
);
353 RSSVAL(buf
,offset
+8,recs
[i
].rdlength
);
354 memcpy(buf
+offset
+10,recs
[i
].rdata
,recs
[i
].rdlength
);
355 offset
+= 10+recs
[i
].rdlength
;
356 ret
+= 10+recs
[i
].rdlength
;
362 /*******************************************************************
363 parse a dgram packet. Return False if the packet can't be parsed
364 or is invalid for some reason, True otherwise
366 this is documented in section 4.4.1 of RFC1002
367 ******************************************************************/
368 static BOOL
parse_dgram(char *inbuf
,int length
,struct dgram_packet
*dgram
)
373 bzero((char *)dgram
,sizeof(*dgram
));
375 if (length
< 14) return(False
);
377 dgram
->header
.msg_type
= CVAL(inbuf
,0);
378 flags
= CVAL(inbuf
,1);
379 dgram
->header
.flags
.node_type
= (enum node_type
)((flags
>>2)&3);
380 if (flags
& 1) dgram
->header
.flags
.more
= True
;
381 if (flags
& 2) dgram
->header
.flags
.first
= True
;
382 dgram
->header
.dgm_id
= RSVAL(inbuf
,2);
383 putip((char *)&dgram
->header
.source_ip
,inbuf
+4);
384 dgram
->header
.source_port
= RSVAL(inbuf
,8);
385 dgram
->header
.dgm_length
= RSVAL(inbuf
,10);
386 dgram
->header
.packet_offset
= RSVAL(inbuf
,12);
390 if (dgram
->header
.msg_type
== 0x10 ||
391 dgram
->header
.msg_type
== 0x11 ||
392 dgram
->header
.msg_type
== 0x12) {
393 offset
+= parse_nmb_name(inbuf
,offset
,length
,&dgram
->source_name
);
394 offset
+= parse_nmb_name(inbuf
,offset
,length
,&dgram
->dest_name
);
397 if (offset
>= length
|| (length
-offset
> sizeof(dgram
->data
)))
400 dgram
->datasize
= length
-offset
;
401 memcpy(dgram
->data
,inbuf
+offset
,dgram
->datasize
);
407 /*******************************************************************
408 parse a nmb packet. Return False if the packet can't be parsed
409 or is invalid for some reason, True otherwise
410 ******************************************************************/
411 static BOOL
parse_nmb(char *inbuf
,int length
,struct nmb_packet
*nmb
)
415 bzero((char *)nmb
,sizeof(*nmb
));
417 if (length
< 12) return(False
);
419 /* parse the header */
420 nmb
->header
.name_trn_id
= RSVAL(inbuf
,0);
421 nmb
->header
.opcode
= (CVAL(inbuf
,2) >> 3) & 0xF;
422 nmb
->header
.response
= ((CVAL(inbuf
,2)>>7)&1)?True
:False
;
423 nm_flags
= ((CVAL(inbuf
,2) & 0x7) << 4) + (CVAL(inbuf
,3)>>4);
424 nmb
->header
.nm_flags
.bcast
= (nm_flags
&1)?True
:False
;
425 nmb
->header
.nm_flags
.recursion_available
= (nm_flags
&8)?True
:False
;
426 nmb
->header
.nm_flags
.recursion_desired
= (nm_flags
&0x10)?True
:False
;
427 nmb
->header
.nm_flags
.trunc
= (nm_flags
&0x20)?True
:False
;
428 nmb
->header
.nm_flags
.authoritative
= (nm_flags
&0x40)?True
:False
;
429 nmb
->header
.rcode
= CVAL(inbuf
,3) & 0xF;
430 nmb
->header
.qdcount
= RSVAL(inbuf
,4);
431 nmb
->header
.ancount
= RSVAL(inbuf
,6);
432 nmb
->header
.nscount
= RSVAL(inbuf
,8);
433 nmb
->header
.arcount
= RSVAL(inbuf
,10);
435 if (nmb
->header
.qdcount
) {
436 offset
= parse_nmb_name(inbuf
,12,length
,&nmb
->question
.question_name
);
437 if (!offset
) return(False
);
439 if (length
- (12+offset
) < 4) return(False
);
440 nmb
->question
.question_type
= RSVAL(inbuf
,12+offset
);
441 nmb
->question
.question_class
= RSVAL(inbuf
,12+offset
+2);
448 /* and any resource records */
449 if (nmb
->header
.ancount
&&
450 !parse_alloc_res_rec(inbuf
,&offset
,length
,&nmb
->answers
,
451 nmb
->header
.ancount
))
454 if (nmb
->header
.nscount
&&
455 !parse_alloc_res_rec(inbuf
,&offset
,length
,&nmb
->nsrecs
,
456 nmb
->header
.nscount
))
459 if (nmb
->header
.arcount
&&
460 !parse_alloc_res_rec(inbuf
,&offset
,length
,&nmb
->additional
,
461 nmb
->header
.arcount
))
467 /*******************************************************************
468 free up any resources associated with an nmb packet
469 ******************************************************************/
470 void free_nmb_packet(struct nmb_packet
*nmb
)
472 if (nmb
->answers
) free(nmb
->answers
);
473 if (nmb
->nsrecs
) free(nmb
->nsrecs
);
474 if (nmb
->additional
) free(nmb
->additional
);
477 /*******************************************************************
478 free up any resources associated with a packet
479 ******************************************************************/
480 void free_packet(struct packet_struct
*packet
)
482 if (packet
->packet_type
== NMB_PACKET
)
483 free_nmb_packet(&packet
->packet
.nmb
);
487 /*******************************************************************
488 read a packet from a socket and parse it, returning a packet ready
489 to be used or put on the queue. This assumes a UDP socket
490 ******************************************************************/
491 struct packet_struct
*read_packet(int fd
,enum packet_type packet_type
)
493 extern struct in_addr lastip
;
495 struct packet_struct
*packet
;
496 char buf
[MAX_DGRAM_SIZE
];
500 length
= read_udp_socket(fd
,buf
,sizeof(buf
));
501 if (length
< MIN_DGRAM_SIZE
) return(NULL
);
503 packet
= (struct packet_struct
*)malloc(sizeof(*packet
));
504 if (!packet
) return(NULL
);
509 packet
->port
= lastport
;
511 packet
->timestamp
= time(NULL
);
512 packet
->packet_type
= packet_type
;
516 ok
= parse_nmb(buf
,length
,&packet
->packet
.nmb
);
520 ok
= parse_dgram(buf
,length
,&packet
->packet
.dgram
);
530 DEBUG(5,("%s received a packet of len %d from (%s) port %d\n",
531 timestring(),length
,inet_ntoa(packet
->ip
),packet
->port
));
537 /*******************************************************************
538 send a udp packet on a already open socket
539 ******************************************************************/
540 static BOOL
send_udp(int fd
,char *buf
,int len
,struct in_addr ip
,int port
)
543 struct sockaddr_in sock_out
;
545 /* set the address and port */
546 bzero((char *)&sock_out
,sizeof(sock_out
));
547 putip((char *)&sock_out
.sin_addr
,(char *)&ip
);
548 sock_out
.sin_port
= htons( port
);
549 sock_out
.sin_family
= AF_INET
;
551 DEBUG(5,("%s sending a packet of len %d to (%s) on port %d\n",
552 timestring(),len
,inet_ntoa(ip
),port
));
554 ret
= (sendto(fd
,buf
,len
,0,(struct sockaddr
*)&sock_out
,
555 sizeof(sock_out
)) >= 0);
558 DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n",
559 inet_ntoa(ip
),port
,strerror(errno
)));
567 /*******************************************************************
568 build a dgram packet ready for sending
570 XXXX This currently doesn't handle packets too big for one
571 datagram. It should split them and use the packet_offset, more and
572 first flags to handle the fragmentation. Yuck.
573 ******************************************************************/
574 static int build_dgram(char *buf
,struct packet_struct
*p
)
576 struct dgram_packet
*dgram
= &p
->packet
.dgram
;
577 unsigned char *ubuf
= (unsigned char *)buf
;
580 /* put in the header */
581 ubuf
[0] = dgram
->header
.msg_type
;
582 ubuf
[1] = (((int)dgram
->header
.flags
.node_type
)<<2);
583 if (dgram
->header
.flags
.more
) ubuf
[1] |= 1;
584 if (dgram
->header
.flags
.first
) ubuf
[1] |= 2;
585 RSSVAL(ubuf
,2,dgram
->header
.dgm_id
);
586 putip(ubuf
+4,(char *)&dgram
->header
.source_ip
);
587 RSSVAL(ubuf
,8,dgram
->header
.source_port
);
588 RSSVAL(ubuf
,12,dgram
->header
.packet_offset
);
592 if (dgram
->header
.msg_type
== 0x10 ||
593 dgram
->header
.msg_type
== 0x11 ||
594 dgram
->header
.msg_type
== 0x12) {
595 offset
+= put_nmb_name((char *)ubuf
,offset
,&dgram
->source_name
);
596 offset
+= put_nmb_name((char *)ubuf
,offset
,&dgram
->dest_name
);
599 memcpy(ubuf
+offset
,dgram
->data
,dgram
->datasize
);
600 offset
+= dgram
->datasize
;
602 /* automatically set the dgm_length */
603 dgram
->header
.dgm_length
= offset
;
604 RSSVAL(ubuf
,10,dgram
->header
.dgm_length
);
609 /*******************************************************************
611 ******************************************************************/
612 void make_nmb_name(struct nmb_name
*n
,char *name
,int type
,char *this_scope
)
614 strcpy(n
->name
,name
);
617 strcpy(n
->scope
,this_scope
);
621 /*******************************************************************
622 build a nmb packet ready for sending
624 XXXX this currently relies on not being passed something that expands
625 to a packet too big for the buffer. Eventually this should be
626 changed to set the trunc bit so the receiver can request the rest
627 via tcp (when that becomes supported)
628 ******************************************************************/
629 static int build_nmb(char *buf
,struct packet_struct
*p
)
631 struct nmb_packet
*nmb
= &p
->packet
.nmb
;
632 unsigned char *ubuf
= (unsigned char *)buf
;
635 /* put in the header */
636 RSSVAL(ubuf
,offset
,nmb
->header
.name_trn_id
);
637 ubuf
[offset
+2] = (nmb
->header
.opcode
& 0xF) << 3;
638 if (nmb
->header
.response
) ubuf
[offset
+2] |= (1<<7);
639 if (nmb
->header
.nm_flags
.authoritative
&&
640 nmb
->header
.response
) ubuf
[offset
+2] |= 0x4;
641 if (nmb
->header
.nm_flags
.trunc
) ubuf
[offset
+2] |= 0x2;
642 if (nmb
->header
.nm_flags
.recursion_desired
) ubuf
[offset
+2] |= 0x1;
643 if (nmb
->header
.nm_flags
.recursion_available
&&
644 nmb
->header
.response
) ubuf
[offset
+3] |= 0x80;
645 if (nmb
->header
.nm_flags
.bcast
) ubuf
[offset
+3] |= 0x10;
646 ubuf
[offset
+3] |= (nmb
->header
.rcode
& 0xF);
648 RSSVAL(ubuf
,offset
+4,nmb
->header
.qdcount
);
649 RSSVAL(ubuf
,offset
+6,nmb
->header
.ancount
);
650 RSSVAL(ubuf
,offset
+8,nmb
->header
.nscount
);
651 RSSVAL(ubuf
,offset
+10,nmb
->header
.arcount
);
654 if (nmb
->header
.qdcount
) {
655 /* XXXX this doesn't handle a qdcount of > 1 */
656 offset
+= put_nmb_name((char *)ubuf
,offset
,&nmb
->question
.question_name
);
657 RSSVAL(ubuf
,offset
,nmb
->question
.question_type
);
658 RSSVAL(ubuf
,offset
+2,nmb
->question
.question_class
);
662 if (nmb
->header
.ancount
)
663 offset
+= put_res_rec((char *)ubuf
,offset
,nmb
->answers
,
664 nmb
->header
.ancount
);
666 if (nmb
->header
.nscount
)
667 offset
+= put_res_rec((char *)ubuf
,offset
,nmb
->nsrecs
,
668 nmb
->header
.nscount
);
670 if (nmb
->header
.arcount
)
671 offset
+= put_res_rec((char *)ubuf
,offset
,nmb
->additional
,
672 nmb
->header
.arcount
);
678 /*******************************************************************
680 ******************************************************************/
681 BOOL
send_packet(struct packet_struct
*p
)
686 bzero(buf
,sizeof(buf
));
688 switch (p
->packet_type
)
691 len
= build_nmb(buf
,p
);
695 len
= build_dgram(buf
,p
);
699 if (!len
) return(False
);
701 return(send_udp(p
->fd
,buf
,len
,p
->ip
,p
->port
));
704 /****************************************************************************
705 receive a packet with timeout on a open UDP filedescriptor
706 The timeout is in milliseconds
707 ***************************************************************************/
708 struct packet_struct
*receive_packet(int fd
,enum packet_type type
,int t
)
711 struct timeval timeout
;
715 timeout
.tv_sec
= t
/1000;
716 timeout
.tv_usec
= 1000*(t
%1000);
718 sys_select(&fds
,&timeout
);
720 if (FD_ISSET(fd
,&fds
))
721 return(read_packet(fd
,type
));