mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
added the unexpected packet database (unexpected.tdb)
this means "nmblookup -S" now always works, even with broken servers
the database stores all unexpected replies and these can be accessed
by any client.
while doing this I cleaned up a couple of functions, and put in place
a better trn_id generator. in most places the code got quite a bit
simpler due to the addition of simple helper functions.
I haven't yet put the code in to take advantage of this for pdc
replies - that will be next. Jeremys pdc finding code will then work :)
(This used to be commit 280e6359d3
)
This commit is contained in:
parent
c0ad729de6
commit
574788039f
@ -109,7 +109,7 @@ PARAM_OBJ = param/loadparm.o param/params.o
|
||||
LIBSMB_OBJ = libsmb/clientgen.o libsmb/namequery.o libsmb/nmblib.o \
|
||||
libsmb/nterr.o libsmb/smbdes.o libsmb/smbencrypt.o \
|
||||
libsmb/smberr.o libsmb/credentials.o libsmb/pwd_cache.o \
|
||||
libsmb/passchange.o
|
||||
libsmb/passchange.o libsmb/unexpected.o
|
||||
|
||||
RPC_SERVER_OBJ = rpc_server/srv_lsa.o \
|
||||
rpc_server/srv_lsa_hnd.o rpc_server/srv_netlog.o \
|
||||
|
@ -138,6 +138,7 @@
|
||||
#define NMBD_MAX_TTL (24*60*60)
|
||||
#define LPQ_LOCK_TIMEOUT (5)
|
||||
#define NMBD_INTERFACES_RELOAD (120)
|
||||
#define NMBD_UNEXPECTED_TIMEOUT (15)
|
||||
|
||||
/* the following are in milliseconds */
|
||||
#define LOCK_RETRY_TIMEOUT (100)
|
||||
|
@ -600,10 +600,10 @@ BOOL deal_with_creds(uchar sess_key[8],
|
||||
/*The following definitions come from libsmb/namequery.c */
|
||||
|
||||
BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
|
||||
struct in_addr to_ip,char *master,char *rname,
|
||||
void (*fn)(struct packet_struct *));
|
||||
struct in_addr *name_query(int fd,const char *name,int name_type, BOOL bcast,BOOL recurse,
|
||||
struct in_addr to_ip, int *count, void (*fn)(struct packet_struct *));
|
||||
struct in_addr to_ip,char *master,char *rname);
|
||||
struct in_addr *name_query(int fd,const char *name,int name_type,
|
||||
BOOL bcast,BOOL recurse,
|
||||
struct in_addr to_ip, int *count);
|
||||
FILE *startlmhosts(char *fname);
|
||||
BOOL getlmhostsent( FILE *fp, pstring name, int *name_type, struct in_addr *ipaddr);
|
||||
void endlmhosts(FILE *fp);
|
||||
@ -618,11 +618,15 @@ void debug_nmb_packet(struct packet_struct *p);
|
||||
char *nmb_namestr(struct nmb_name *n);
|
||||
struct packet_struct *copy_packet(struct packet_struct *packet);
|
||||
void free_packet(struct packet_struct *packet);
|
||||
struct packet_struct *parse_packet(char *buf,int length,
|
||||
enum packet_type packet_type);
|
||||
struct packet_struct *read_packet(int fd,enum packet_type packet_type);
|
||||
void make_nmb_name( struct nmb_name *n, const char *name, int type, const char *this_scope );
|
||||
BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2);
|
||||
int build_packet(char *buf, struct packet_struct *p);
|
||||
BOOL send_packet(struct packet_struct *p);
|
||||
struct packet_struct *receive_packet(int fd,enum packet_type type,int t);
|
||||
struct packet_struct *receive_reply_packet(int fd, int t, int trn_id);
|
||||
void sort_query_replies(char *data, int n, struct in_addr ip);
|
||||
|
||||
/*The following definitions come from libsmb/nterr.c */
|
||||
@ -674,6 +678,12 @@ BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[
|
||||
|
||||
char *smb_errstr(char *inbuf);
|
||||
|
||||
/*The following definitions come from libsmb/unexpected.c */
|
||||
|
||||
void unexpected_packet(struct packet_struct *p);
|
||||
void clear_unexpected(time_t t);
|
||||
struct packet_struct *receive_unexpected_137(int trn_id);
|
||||
|
||||
/*The following definitions come from locking/locking.c */
|
||||
|
||||
BOOL is_locked(files_struct *fsp,connection_struct *conn,
|
||||
@ -697,7 +707,6 @@ BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type);
|
||||
BOOL remove_share_oplock(files_struct *fsp);
|
||||
BOOL downgrade_share_oplock(files_struct *fsp);
|
||||
BOOL modify_share_mode(files_struct *fsp, int new_mode, uint16 new_oplock);
|
||||
int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf);
|
||||
int share_mode_forall(void (*fn)(share_mode_entry *, char *));
|
||||
|
||||
/*The following definitions come from nmbd/asyncdns.c */
|
||||
|
@ -28,6 +28,23 @@ extern int DEBUGLEVEL;
|
||||
/* nmbd.c sets this to True. */
|
||||
BOOL global_in_nmbd = False;
|
||||
|
||||
/****************************************************************************
|
||||
generate a random trn_id
|
||||
****************************************************************************/
|
||||
static int generate_trn_id(void)
|
||||
{
|
||||
static int trn_id;
|
||||
|
||||
if (trn_id == 0) {
|
||||
srandom(getpid());
|
||||
}
|
||||
|
||||
trn_id = random();
|
||||
|
||||
return trn_id % (unsigned)0x7FFF;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
Interpret a node status response.
|
||||
****************************************************************************/
|
||||
@ -85,11 +102,10 @@ static void _interpret_node_status(char *p, char *master,char *rname)
|
||||
/****************************************************************************
|
||||
Internal function handling a netbios name status query on a host.
|
||||
**************************************************************************/
|
||||
|
||||
static BOOL internal_name_status(int fd,char *name,int name_type,BOOL recurse,
|
||||
struct in_addr to_ip,char *master,char *rname, BOOL verbose,
|
||||
void (*fn_interpret_node_status)(char *, char *,char *),
|
||||
void (*fn)(struct packet_struct *))
|
||||
struct in_addr to_ip,char *master,
|
||||
char *rname, BOOL verbose,
|
||||
void (*fn_interpret_node_status)(char *, char *,char *))
|
||||
{
|
||||
BOOL found=False;
|
||||
int retries = 2;
|
||||
@ -98,15 +114,10 @@ static BOOL internal_name_status(int fd,char *name,int name_type,BOOL recurse,
|
||||
struct packet_struct p;
|
||||
struct packet_struct *p2;
|
||||
struct nmb_packet *nmb = &p.packet.nmb;
|
||||
static int name_trn_id = 0;
|
||||
|
||||
memset((char *)&p,'\0',sizeof(p));
|
||||
|
||||
if (!name_trn_id) name_trn_id = ((unsigned)time(NULL)%(unsigned)0x7FFF) +
|
||||
((unsigned)getpid()%(unsigned)100);
|
||||
name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
|
||||
|
||||
nmb->header.name_trn_id = name_trn_id;
|
||||
nmb->header.name_trn_id = generate_trn_id();
|
||||
nmb->header.opcode = 0;
|
||||
nmb->header.response = False;
|
||||
nmb->header.nm_flags.bcast = False;
|
||||
@ -139,51 +150,42 @@ static BOOL internal_name_status(int fd,char *name,int name_type,BOOL recurse,
|
||||
retries--;
|
||||
|
||||
while (1) {
|
||||
struct timeval tval2;
|
||||
GetTimeOfDay(&tval2);
|
||||
if (TvalDiff(&tval,&tval2) > retry_time) {
|
||||
if (!retries)
|
||||
break;
|
||||
if (!found && !send_packet(&p))
|
||||
return False;
|
||||
GetTimeOfDay(&tval);
|
||||
retries--;
|
||||
}
|
||||
|
||||
if ((p2=receive_packet(fd,NMB_PACKET,90))) {
|
||||
struct nmb_packet *nmb2 = &p2->packet.nmb;
|
||||
debug_nmb_packet(p2);
|
||||
|
||||
if (nmb->header.name_trn_id != nmb2->header.name_trn_id ||
|
||||
!nmb2->header.response) {
|
||||
/* its not for us - maybe deal with it later */
|
||||
if (fn)
|
||||
fn(p2);
|
||||
else
|
||||
free_packet(p2);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (nmb2->header.opcode != 0 ||
|
||||
nmb2->header.nm_flags.bcast ||
|
||||
nmb2->header.rcode ||
|
||||
!nmb2->header.ancount ||
|
||||
nmb2->answers->rr_type != 0x21) {
|
||||
/* XXXX what do we do with this? could be a redirect, but
|
||||
we'll discard it for the moment */
|
||||
free_packet(p2);
|
||||
continue;
|
||||
struct timeval tval2;
|
||||
GetTimeOfDay(&tval2);
|
||||
if (TvalDiff(&tval,&tval2) > retry_time) {
|
||||
if (!retries)
|
||||
break;
|
||||
if (!found && !send_packet(&p))
|
||||
return False;
|
||||
GetTimeOfDay(&tval);
|
||||
retries--;
|
||||
}
|
||||
|
||||
if(fn_interpret_node_status)
|
||||
(*fn_interpret_node_status)(&nmb2->answers->rdata[0],master,rname);
|
||||
free_packet(p2);
|
||||
return(True);
|
||||
}
|
||||
if ((p2=receive_reply_packet(fd,90,nmb->header.name_trn_id))) {
|
||||
struct nmb_packet *nmb2 = &p2->packet.nmb;
|
||||
debug_nmb_packet(p2);
|
||||
|
||||
if (nmb2->header.opcode != 0 ||
|
||||
nmb2->header.nm_flags.bcast ||
|
||||
nmb2->header.rcode ||
|
||||
!nmb2->header.ancount ||
|
||||
nmb2->answers->rr_type != 0x21) {
|
||||
/* XXXX what do we do with this? could be a
|
||||
redirect, but we'll discard it for the
|
||||
moment */
|
||||
free_packet(p2);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(fn_interpret_node_status)
|
||||
(*fn_interpret_node_status)(&nmb2->answers->rdata[0],master,rname);
|
||||
free_packet(p2);
|
||||
return(True);
|
||||
}
|
||||
}
|
||||
|
||||
if(verbose)
|
||||
DEBUG(0,("No status response (this is not unusual)\n"));
|
||||
DEBUG(0,("No status response (this is not unusual)\n"));
|
||||
|
||||
return(False);
|
||||
}
|
||||
@ -192,14 +194,12 @@ static BOOL internal_name_status(int fd,char *name,int name_type,BOOL recurse,
|
||||
Do a netbios name status query on a host.
|
||||
The "master" parameter is a hack used for finding workgroups.
|
||||
**************************************************************************/
|
||||
|
||||
BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
|
||||
struct in_addr to_ip,char *master,char *rname,
|
||||
void (*fn)(struct packet_struct *))
|
||||
struct in_addr to_ip,char *master,char *rname)
|
||||
{
|
||||
return internal_name_status(fd,name,name_type,recurse,
|
||||
to_ip,master,rname,True,
|
||||
_interpret_node_status, fn);
|
||||
return internal_name_status(fd,name,name_type,recurse,
|
||||
to_ip,master,rname,True,
|
||||
_interpret_node_status);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -208,8 +208,9 @@ BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
|
||||
*count will be set to the number of addresses returned.
|
||||
****************************************************************************/
|
||||
|
||||
struct in_addr *name_query(int fd,const char *name,int name_type, BOOL bcast,BOOL recurse,
|
||||
struct in_addr to_ip, int *count, void (*fn)(struct packet_struct *))
|
||||
struct in_addr *name_query(int fd,const char *name,int name_type,
|
||||
BOOL bcast,BOOL recurse,
|
||||
struct in_addr to_ip, int *count)
|
||||
{
|
||||
BOOL found=False;
|
||||
int i, retries = 3;
|
||||
@ -218,17 +219,12 @@ struct in_addr *name_query(int fd,const char *name,int name_type, BOOL bcast,BOO
|
||||
struct packet_struct p;
|
||||
struct packet_struct *p2;
|
||||
struct nmb_packet *nmb = &p.packet.nmb;
|
||||
static int name_trn_id = 0;
|
||||
struct in_addr *ip_list = NULL;
|
||||
|
||||
memset((char *)&p,'\0',sizeof(p));
|
||||
(*count) = 0;
|
||||
|
||||
if (!name_trn_id) name_trn_id = ((unsigned)time(NULL)%(unsigned)0x7FFF) +
|
||||
((unsigned)getpid()%(unsigned)100);
|
||||
name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
|
||||
|
||||
nmb->header.name_trn_id = name_trn_id;
|
||||
nmb->header.name_trn_id = generate_trn_id();
|
||||
nmb->header.opcode = 0;
|
||||
nmb->header.response = False;
|
||||
nmb->header.nm_flags.bcast = bcast;
|
||||
@ -262,79 +258,57 @@ struct in_addr *name_query(int fd,const char *name,int name_type, BOOL bcast,BOO
|
||||
|
||||
while (1)
|
||||
{
|
||||
struct timeval tval2;
|
||||
GetTimeOfDay(&tval2);
|
||||
if (TvalDiff(&tval,&tval2) > retry_time)
|
||||
{
|
||||
if (!retries)
|
||||
break;
|
||||
if (!found && !send_packet(&p))
|
||||
return NULL;
|
||||
GetTimeOfDay(&tval);
|
||||
retries--;
|
||||
}
|
||||
|
||||
if ((p2=receive_packet(fd,NMB_PACKET,90)))
|
||||
{
|
||||
struct nmb_packet *nmb2 = &p2->packet.nmb;
|
||||
debug_nmb_packet(p2);
|
||||
|
||||
if (nmb->header.name_trn_id != nmb2->header.name_trn_id ||
|
||||
!nmb2->header.response)
|
||||
{
|
||||
/*
|
||||
* Its not for us - maybe deal with it later
|
||||
* (put it on the queue?).
|
||||
*/
|
||||
if (fn)
|
||||
fn(p2);
|
||||
else
|
||||
free_packet(p2);
|
||||
continue;
|
||||
}
|
||||
struct timeval tval2;
|
||||
GetTimeOfDay(&tval2);
|
||||
if (TvalDiff(&tval,&tval2) > retry_time) {
|
||||
if (!retries)
|
||||
break;
|
||||
if (!found && !send_packet(&p))
|
||||
return NULL;
|
||||
GetTimeOfDay(&tval);
|
||||
retries--;
|
||||
}
|
||||
|
||||
if (nmb2->header.opcode != 0 ||
|
||||
nmb2->header.nm_flags.bcast ||
|
||||
nmb2->header.rcode ||
|
||||
!nmb2->header.ancount)
|
||||
{
|
||||
/*
|
||||
* XXXX what do we do with this? Could be a redirect, but
|
||||
* we'll discard it for the moment.
|
||||
*/
|
||||
free_packet(p2);
|
||||
continue;
|
||||
}
|
||||
if ((p2=receive_reply_packet(fd,90,nmb->header.name_trn_id))) {
|
||||
struct nmb_packet *nmb2 = &p2->packet.nmb;
|
||||
debug_nmb_packet(p2);
|
||||
|
||||
if (nmb2->header.opcode != 0 ||
|
||||
nmb2->header.nm_flags.bcast ||
|
||||
nmb2->header.rcode ||
|
||||
!nmb2->header.ancount) {
|
||||
/*
|
||||
* XXXX what do we do with this? Could be a
|
||||
* redirect, but we'll discard it for the
|
||||
* moment. */
|
||||
free_packet(p2);
|
||||
continue;
|
||||
}
|
||||
|
||||
ip_list = (struct in_addr *)Realloc(ip_list, sizeof(ip_list[0]) *
|
||||
((*count)+nmb2->answers->rdlength/6));
|
||||
if (ip_list)
|
||||
{
|
||||
DEBUG(fn?3:2,("Got a positive name query response from %s ( ",
|
||||
inet_ntoa(p2->ip)));
|
||||
for (i=0;i<nmb2->answers->rdlength/6;i++)
|
||||
{
|
||||
putip((char *)&ip_list[(*count)],&nmb2->answers->rdata[2+i*6]);
|
||||
DEBUG(fn?3:2,("%s ",inet_ntoa(ip_list[(*count)])));
|
||||
(*count)++;
|
||||
}
|
||||
DEBUG(fn?3:2,(")\n"));
|
||||
}
|
||||
ip_list = (struct in_addr *)Realloc(ip_list, sizeof(ip_list[0]) *
|
||||
((*count)+nmb2->answers->rdlength/6));
|
||||
if (ip_list) {
|
||||
DEBUG(2,("Got a positive name query response from %s ( ",
|
||||
inet_ntoa(p2->ip)));
|
||||
for (i=0;i<nmb2->answers->rdlength/6;i++) {
|
||||
putip((char *)&ip_list[(*count)],&nmb2->answers->rdata[2+i*6]);
|
||||
DEBUG(2,("%s ",inet_ntoa(ip_list[(*count)])));
|
||||
(*count)++;
|
||||
}
|
||||
DEBUG(2,(")\n"));
|
||||
}
|
||||
|
||||
found=True;
|
||||
retries=0;
|
||||
free_packet(p2);
|
||||
if (fn)
|
||||
break;
|
||||
|
||||
/*
|
||||
* If we're doing a unicast lookup we only
|
||||
* expect one reply. Don't wait the full 2
|
||||
* seconds if we got one. JRA.
|
||||
*/
|
||||
if(!bcast && found)
|
||||
break;
|
||||
}
|
||||
found=True;
|
||||
retries=0;
|
||||
free_packet(p2);
|
||||
/*
|
||||
* If we're doing a unicast lookup we only
|
||||
* expect one reply. Don't wait the full 2
|
||||
* seconds if we got one. JRA.
|
||||
*/
|
||||
if(!bcast && found)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ip_list;
|
||||
@ -483,7 +457,7 @@ static BOOL resolve_bcast(const char *name, int name_type,
|
||||
/* Done this way to fix compiler error on IRIX 5.x */
|
||||
sendto_ip = *iface_bcast(*iface_n_ip(i));
|
||||
*return_ip_list = name_query(sock, name, name_type, True,
|
||||
True, sendto_ip, return_count, NULL);
|
||||
True, sendto_ip, return_count);
|
||||
if(*return_ip_list != NULL) {
|
||||
close(sock);
|
||||
return True;
|
||||
@ -532,7 +506,7 @@ static BOOL resolve_wins(const char *name, int name_type,
|
||||
|
||||
if (sock != -1) {
|
||||
*return_iplist = name_query(sock, name, name_type, False,
|
||||
True, wins_ip, return_count, NULL);
|
||||
True, wins_ip, return_count);
|
||||
if(*return_iplist != NULL) {
|
||||
close(sock);
|
||||
return True;
|
||||
@ -784,8 +758,8 @@ BOOL lookup_pdc_name(const char *srcname, const char *domain, struct in_addr *pd
|
||||
*pdc_name = '\0';
|
||||
|
||||
ret = internal_name_status(sock,"*SMBSERVER",0x20,True,
|
||||
*pdc_ip,NULL,pdc_name,False,
|
||||
_lookup_pdc_name,NULL);
|
||||
*pdc_ip,NULL,pdc_name,False,
|
||||
_lookup_pdc_name);
|
||||
|
||||
close(sock);
|
||||
|
||||
@ -815,7 +789,6 @@ BOOL lookup_pdc_name(const char *srcname, const char *domain, struct in_addr *pd
|
||||
struct sockaddr_in sock_name;
|
||||
int sock_len = sizeof(sock_name);
|
||||
const char *mailslot = "\\MAILSLOT\\NET\\NETLOGON";
|
||||
static int name_trn_id = 0;
|
||||
char buffer[1024];
|
||||
char *bufp;
|
||||
int sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True );
|
||||
@ -852,10 +825,6 @@ BOOL lookup_pdc_name(const char *srcname, const char *domain, struct in_addr *pd
|
||||
bufp += 8;
|
||||
len = PTR_DIFF(bufp,buffer);
|
||||
|
||||
if (!name_trn_id)
|
||||
name_trn_id = ((unsigned)time(NULL)%(unsigned)0x7FFF) + ((unsigned)getpid()%(unsigned)100);
|
||||
name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
|
||||
|
||||
memset((char *)&p,'\0',sizeof(p));
|
||||
|
||||
/* DIRECT GROUP or UNIQUE datagram. */
|
||||
@ -863,7 +832,7 @@ BOOL lookup_pdc_name(const char *srcname, const char *domain, struct in_addr *pd
|
||||
dgram->header.flags.node_type = M_NODE;
|
||||
dgram->header.flags.first = True;
|
||||
dgram->header.flags.more = False;
|
||||
dgram->header.dgm_id = name_trn_id;
|
||||
dgram->header.dgm_id = generate_trn_id();
|
||||
dgram->header.source_ip = sock_name.sin_addr;
|
||||
dgram->header.source_port = ntohs(sock_name.sin_port);
|
||||
dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */
|
||||
|
@ -677,56 +677,70 @@ void free_packet(struct packet_struct *packet)
|
||||
free(packet);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
parse a packet buffer into a packet structure
|
||||
******************************************************************/
|
||||
struct packet_struct *parse_packet(char *buf,int length,
|
||||
enum packet_type packet_type)
|
||||
{
|
||||
extern struct in_addr lastip;
|
||||
extern int lastport;
|
||||
struct packet_struct *p;
|
||||
BOOL ok=False;
|
||||
|
||||
p = (struct packet_struct *)malloc(sizeof(*p));
|
||||
if (!p) return(NULL);
|
||||
|
||||
p->next = NULL;
|
||||
p->prev = NULL;
|
||||
p->ip = lastip;
|
||||
p->port = lastport;
|
||||
p->locked = False;
|
||||
p->timestamp = time(NULL);
|
||||
p->packet_type = packet_type;
|
||||
|
||||
switch (packet_type) {
|
||||
case NMB_PACKET:
|
||||
ok = parse_nmb(buf,length,&p->packet.nmb);
|
||||
break;
|
||||
|
||||
case DGRAM_PACKET:
|
||||
ok = parse_dgram(buf,length,&p->packet.dgram);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!ok) {
|
||||
free_packet(p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
read a packet from a socket and parse it, returning a packet ready
|
||||
to be used or put on the queue. This assumes a UDP socket
|
||||
******************************************************************/
|
||||
struct packet_struct *read_packet(int fd,enum packet_type packet_type)
|
||||
{
|
||||
extern struct in_addr lastip;
|
||||
extern int lastport;
|
||||
struct packet_struct *packet;
|
||||
char buf[MAX_DGRAM_SIZE];
|
||||
int length;
|
||||
BOOL ok=False;
|
||||
|
||||
length = read_udp_socket(fd,buf,sizeof(buf));
|
||||
if (length < MIN_DGRAM_SIZE) return(NULL);
|
||||
struct packet_struct *packet;
|
||||
char buf[MAX_DGRAM_SIZE];
|
||||
int length;
|
||||
|
||||
length = read_udp_socket(fd,buf,sizeof(buf));
|
||||
if (length < MIN_DGRAM_SIZE) return(NULL);
|
||||
|
||||
packet = parse_packet(buf, length, packet_type);
|
||||
if (!packet) return NULL;
|
||||
|
||||
packet = (struct packet_struct *)malloc(sizeof(*packet));
|
||||
if (!packet) return(NULL);
|
||||
|
||||
packet->next = NULL;
|
||||
packet->prev = NULL;
|
||||
packet->ip = lastip;
|
||||
packet->port = lastport;
|
||||
packet->fd = fd;
|
||||
packet->locked = False;
|
||||
packet->timestamp = time(NULL);
|
||||
packet->packet_type = packet_type;
|
||||
switch (packet_type)
|
||||
{
|
||||
case NMB_PACKET:
|
||||
ok = parse_nmb(buf,length,&packet->packet.nmb);
|
||||
break;
|
||||
|
||||
case DGRAM_PACKET:
|
||||
ok = parse_dgram(buf,length,&packet->packet.dgram);
|
||||
break;
|
||||
}
|
||||
if (!ok) {
|
||||
DEBUG(10,("read_packet: discarding packet id = %d\n",
|
||||
packet->packet.nmb.header.name_trn_id));
|
||||
free_packet(packet);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
num_good_receives++;
|
||||
|
||||
DEBUG(5,("Received a packet of len %d from (%s) port %d\n",
|
||||
length, inet_ntoa(packet->ip), packet->port ) );
|
||||
|
||||
return(packet);
|
||||
packet->fd = fd;
|
||||
|
||||
num_good_receives++;
|
||||
|
||||
DEBUG(5,("Received a packet of len %d from (%s) port %d\n",
|
||||
length, inet_ntoa(packet->ip), packet->port ) );
|
||||
|
||||
return(packet);
|
||||
}
|
||||
|
||||
|
||||
@ -900,6 +914,26 @@ static int build_nmb(char *buf,struct packet_struct *p)
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
linearise a packet
|
||||
******************************************************************/
|
||||
int build_packet(char *buf, struct packet_struct *p)
|
||||
{
|
||||
int len = 0;
|
||||
|
||||
switch (p->packet_type) {
|
||||
case NMB_PACKET:
|
||||
len = build_nmb(buf,p);
|
||||
break;
|
||||
|
||||
case DGRAM_PACKET:
|
||||
len = build_dgram(buf,p);
|
||||
break;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
send a packet_struct
|
||||
******************************************************************/
|
||||
@ -910,17 +944,7 @@ BOOL send_packet(struct packet_struct *p)
|
||||
|
||||
memset(buf,'\0',sizeof(buf));
|
||||
|
||||
switch (p->packet_type)
|
||||
{
|
||||
case NMB_PACKET:
|
||||
len = build_nmb(buf,p);
|
||||
debug_nmb_packet(p);
|
||||
break;
|
||||
|
||||
case DGRAM_PACKET:
|
||||
len = build_dgram(buf,p);
|
||||
break;
|
||||
}
|
||||
len = build_packet(buf, p);
|
||||
|
||||
if (!len) return(False);
|
||||
|
||||
@ -933,20 +957,42 @@ BOOL send_packet(struct packet_struct *p)
|
||||
***************************************************************************/
|
||||
struct packet_struct *receive_packet(int fd,enum packet_type type,int t)
|
||||
{
|
||||
fd_set fds;
|
||||
struct timeval timeout;
|
||||
fd_set fds;
|
||||
struct timeval timeout;
|
||||
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(fd,&fds);
|
||||
timeout.tv_sec = t/1000;
|
||||
timeout.tv_usec = 1000*(t%1000);
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(fd,&fds);
|
||||
timeout.tv_sec = t/1000;
|
||||
timeout.tv_usec = 1000*(t%1000);
|
||||
|
||||
sys_select(fd+1,&fds,&timeout);
|
||||
sys_select(fd+1,&fds,&timeout);
|
||||
|
||||
if (FD_ISSET(fd,&fds))
|
||||
return(read_packet(fd,type));
|
||||
if (FD_ISSET(fd,&fds))
|
||||
return(read_packet(fd,type));
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
return(NULL);
|
||||
|
||||
/****************************************************************************
|
||||
receive a UDP/137 packet either via UDP or from the unexpected packet
|
||||
queue. The packet must be a reply packet and have the specified trn_id
|
||||
The timeout is in milliseconds
|
||||
***************************************************************************/
|
||||
struct packet_struct *receive_reply_packet(int fd, int t, int trn_id)
|
||||
{
|
||||
struct packet_struct *p;
|
||||
|
||||
p = receive_packet(fd, NMB_PACKET, t);
|
||||
|
||||
if (p && p->packet.nmb.header.response &&
|
||||
p->packet.nmb.header.name_trn_id == trn_id) {
|
||||
return p;
|
||||
}
|
||||
if (p) free_packet(p);
|
||||
|
||||
/* try the unexpected packet queue */
|
||||
return receive_unexpected_137(trn_id);
|
||||
}
|
||||
|
||||
|
||||
|
@ -480,7 +480,7 @@ static void (*traverse_callback)(share_mode_entry *, char *);
|
||||
traverse the whole database with this function, calling traverse_callback
|
||||
on each share mode
|
||||
****************************************************************************/
|
||||
int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf)
|
||||
static int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf)
|
||||
{
|
||||
struct locking_data *data;
|
||||
share_mode_entry *shares;
|
||||
|
@ -457,6 +457,11 @@ static void process(void)
|
||||
*/
|
||||
sync_all_dmbs(t);
|
||||
|
||||
/*
|
||||
* clear the unexpected packet queue
|
||||
*/
|
||||
clear_unexpected(t);
|
||||
|
||||
/*
|
||||
* Reload the services file if we got a sighup.
|
||||
*/
|
||||
|
@ -1402,8 +1402,9 @@ static struct subnet_record *find_subnet_for_nmb_packet( struct packet_struct *p
|
||||
rrec = find_response_record( &subrec, nmb->header.name_trn_id);
|
||||
if(rrec == NULL)
|
||||
{
|
||||
DEBUG(0,("find_subnet_for_nmb_packet: response record not found for response id %hu\n",
|
||||
DEBUG(3,("find_subnet_for_nmb_packet: response record not found for response id %hu\n",
|
||||
nmb->header.name_trn_id));
|
||||
unexpected_packet(p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -95,7 +95,7 @@ static BOOL query_one(char *lookup, unsigned int lookup_type)
|
||||
printf("querying %s on %s\n", lookup, inet_ntoa(bcast_addr));
|
||||
ip_list = name_query(ServerFD,lookup,lookup_type,use_bcast,
|
||||
use_bcast?True:recursion_desired,
|
||||
bcast_addr,&count,NULL);
|
||||
bcast_addr,&count);
|
||||
} else {
|
||||
struct in_addr *bcast;
|
||||
for (j=iface_count() - 1;
|
||||
@ -107,7 +107,7 @@ static BOOL query_one(char *lookup, unsigned int lookup_type)
|
||||
ip_list = name_query(ServerFD,lookup,lookup_type,
|
||||
use_bcast,
|
||||
use_bcast?True:recursion_desired,
|
||||
*bcast,&count,NULL);
|
||||
*bcast,&count);
|
||||
}
|
||||
}
|
||||
|
||||
@ -128,7 +128,7 @@ static BOOL query_one(char *lookup, unsigned int lookup_type)
|
||||
*/
|
||||
if (find_status) {
|
||||
printf("Looking up status of %s\n",inet_ntoa(ip_list[0]));
|
||||
name_status(ServerFD,lookup,lookup_type,True,ip_list[0],NULL,NULL,NULL);
|
||||
name_status(ServerFD,lookup,lookup_type,True,ip_list[0],NULL,NULL);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
@ -243,7 +243,7 @@ int main(int argc,char *argv[])
|
||||
fstrcpy(lookup,"*");
|
||||
ip = *interpret_addr2(argv[i]);
|
||||
printf("Looking up status of %s\n",inet_ntoa(ip));
|
||||
name_status(ServerFD,lookup,lookup_type,True,ip,NULL,NULL,NULL);
|
||||
name_status(ServerFD,lookup,lookup_type,True,ip,NULL,NULL);
|
||||
printf("\n");
|
||||
continue;
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ BOOL nmbd_running(void)
|
||||
interpret_addr("127.0.0.1"), True)) != -1) {
|
||||
if ((ip_list = name_query(fd, "__SAMBA__", 0,
|
||||
True, True, loopback_ip,
|
||||
&count,0)) != NULL) {
|
||||
&count)) != NULL) {
|
||||
free(ip_list);
|
||||
close(fd);
|
||||
return True;
|
||||
|
Loading…
Reference in New Issue
Block a user