summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamba Release Account <samba-bugs@samba.org>1996-10-27 14:22:56 +0000
committerSamba Release Account <samba-bugs@samba.org>1996-10-27 14:22:56 +0000
commitf14a7c5ce8864714fa8fa7f8fe8d630a6ab0861f (patch)
tree6fcdf37e1e643c964d2fee155808dcc3caf190e2
parent697e46373c8fa7b07234f6611c93cf25fe9733ed (diff)
downloadsamba-f14a7c5ce8864714fa8fa7f8fe8d630a6ab0861f.tar.gz
samba-f14a7c5ce8864714fa8fa7f8fe8d630a6ab0861f.tar.bz2
samba-f14a7c5ce8864714fa8fa7f8fe8d630a6ab0861f.zip
severe debugging session for nmbd. in fact, i'm surprised that browsing
in 1.9.16 works at all! question and resource record types for queries and response netbios packets sorted out properly (see rfc1002.txt 4.2.1.3). receipt of browser announcement packets were playing up lkcl (This used to be commit b289db62f1a53f1a68ea48dbfa59720cc778d39c)
-rw-r--r--source3/namedbname.c7
-rw-r--r--source3/namedbsubnet.c17
-rw-r--r--source3/namepacket.c103
-rw-r--r--source3/nameresp.c33
-rw-r--r--source3/nameservreply.c25
-rw-r--r--source3/nameservresp.c36
-rw-r--r--source3/namework.c27
7 files changed, 126 insertions, 122 deletions
diff --git a/source3/namedbname.c b/source3/namedbname.c
index 8f5514be53..c1ec92ea00 100644
--- a/source3/namedbname.c
+++ b/source3/namedbname.c
@@ -149,10 +149,11 @@ struct name_record *find_name(struct name_record *n,
if (name_equal(&ret->name,name))
{
/* self search: self names only */
- if ((search&FIND_SELF) == FIND_SELF &&
- ret->source != SELF)
+ if ((search&FIND_SELF) == FIND_SELF && ret->source != SELF)
+ {
continue;
-
+ }
+
return ret;
}
}
diff --git a/source3/namedbsubnet.c b/source3/namedbsubnet.c
index 16eeb6322e..367179b6c6 100644
--- a/source3/namedbsubnet.c
+++ b/source3/namedbsubnet.c
@@ -87,22 +87,25 @@ struct subnet_record *find_subnet(struct in_addr bcast_ip)
the source ip address. a subnet 255.255.255.255 represents the
WINS list. */
- for (d = subnetlist; d; d = d->next)
+ for (d = subnetlist; d; d = d->next)
{
if (ip_equal(bcast_ip, wins_ip))
{
- if (ip_equal(bcast_ip, d->bcast_ip))
- {
- return d;
- }
+ if (ip_equal(bcast_ip, d->bcast_ip))
+ {
+ return d;
+ }
}
else if (same_net(bcast_ip, d->bcast_ip, d->mask_ip))
{
- return(d);
+ if (!ip_equal(d->bcast_ip, wins_ip))
+ {
+ return d;
+ }
}
}
- return (NULL);
+ return (NULL);
}
diff --git a/source3/namepacket.c b/source3/namepacket.c
index e6677ee10d..84b0a1b355 100644
--- a/source3/namepacket.c
+++ b/source3/namepacket.c
@@ -141,28 +141,29 @@ void initiate_netbios_packet(uint16 *id,
make_nmb_name(&nmb->question.question_name,name,name_type,scope);
- nmb->question.question_type = quest_type;
+ nmb->question.question_type = 0x20;
nmb->question.question_class = 0x1;
if (quest_type == NMB_REG ||
quest_type == NMB_REG_REFRESH ||
quest_type == NMB_REL)
- {
+ {
nmb->additional = &additional_rec;
bzero((char *)nmb->additional,sizeof(*nmb->additional));
nmb->additional->rr_name = nmb->question.question_name;
- nmb->additional->rr_type = nmb->question.question_type;
- nmb->additional->rr_class = nmb->question.question_class;
+ nmb->additional->rr_type = 0x20;
+ nmb->additional->rr_class = 0x1;
if (quest_type == NMB_REG || quest_type == NMB_REG_REFRESH)
- nmb->additional->ttl = lp_max_ttl();
+ nmb->additional->ttl = lp_max_ttl();
else
- nmb->additional->ttl = 0;
+ nmb->additional->ttl = 0;
+
nmb->additional->rdlength = 6;
nmb->additional->rdata[0] = nb_flags;
putip(&nmb->additional->rdata[2],(char *)iface_ip(to_ip));
- }
+ }
p.ip = to_ip;
p.port = NMB_PORT;
@@ -492,58 +493,60 @@ void run_packet_queue()
***************************************************************************/
void listen_for_packets(BOOL run_election)
{
- fd_set fds;
- int selrtn;
- struct timeval timeout;
+ fd_set fds;
+ int selrtn;
+ struct timeval timeout;
-try_again:
+ FD_ZERO(&fds);
+ FD_SET(ClientNMB,&fds);
+ FD_SET(ClientDGRAM,&fds);
- FD_ZERO(&fds);
- FD_SET(ClientNMB,&fds);
- FD_SET(ClientDGRAM,&fds);
+ /* during elections and when expecting a netbios response packet we
+ need to send election packets at tighter intervals
- /* during elections and when expecting a netbios response packet we
- need to send election packets at tighter intervals
+ ideally it needs to be the interval (in ms) between time now and
+ the time we are expecting the next netbios packet */
- ideally it needs to be the interval (in ms) between time now and
- the time we are expecting the next netbios packet */
+ timeout.tv_sec = (run_election||num_response_packets) ? 1:NMBD_SELECT_LOOP;
+ timeout.tv_usec = 0;
- timeout.tv_sec = (run_election||num_response_packets) ? 1 : NMBD_SELECT_LOOP;
- timeout.tv_usec = 0;
+ selrtn = sys_select(&fds,&timeout);
- selrtn = sys_select(&fds,&timeout);
-
- if (FD_ISSET(ClientNMB,&fds))
- {
- struct packet_struct *packet = read_packet(ClientNMB, NMB_PACKET);
- if (packet) {
- if (ismyip(packet->ip) &&
- (packet->port == NMB_PORT || packet->port == DGRAM_PORT)) {
- DEBUG(7,("discarding own packet from %s:%d\n",
- inet_ntoa(packet->ip),packet->port));
- free_packet(packet);
- goto try_again;
- } else {
- queue_packet(packet);
+ if (FD_ISSET(ClientNMB,&fds))
+ {
+ struct packet_struct *packet = read_packet(ClientNMB, NMB_PACKET);
+ if (packet)
+ {
+ if (ismyip(packet->ip) && packet->port == NMB_PORT)
+ {
+ DEBUG(7,("discarding own packet from %s:%d\n",
+ inet_ntoa(packet->ip),packet->port));
+ free_packet(packet);
+ }
+ else
+ {
+ queue_packet(packet);
+ }
+ }
}
- }
- }
- if (FD_ISSET(ClientDGRAM,&fds))
- {
- struct packet_struct *packet = read_packet(ClientDGRAM, DGRAM_PACKET);
- if (packet) {
- if (ismyip(packet->ip) &&
- (packet->port == NMB_PORT || packet->port == DGRAM_PORT)) {
- DEBUG(7,("discarding own packet from %s:%d\n",
- inet_ntoa(packet->ip),packet->port));
- free_packet(packet);
- goto try_again;
- } else {
- queue_packet(packet);
+ if (FD_ISSET(ClientDGRAM,&fds))
+ {
+ struct packet_struct *packet = read_packet(ClientDGRAM, DGRAM_PACKET);
+ if (packet)
+ {
+ if (ismyip(packet->ip) && packet->port == DGRAM_PORT)
+ {
+ DEBUG(7,("discarding own packet from %s:%d\n",
+ inet_ntoa(packet->ip),packet->port));
+ free_packet(packet);
+ }
+ else
+ {
+ queue_packet(packet);
+ }
+ }
}
- }
- }
}
diff --git a/source3/nameresp.c b/source3/nameresp.c
index 9be0f4491f..949bb366bb 100644
--- a/source3/nameresp.c
+++ b/source3/nameresp.c
@@ -134,25 +134,28 @@ static void dead_netbios_entry(struct subnet_record *d,
on that subnet. if we are using a WINS server, then the WINS
server must be dead or deaf.
*/
- if (n->bcast)
+ if (n->num_msgs == 0)
{
- /* broadcast method: implicit acceptance of the name registration
- by not receiving any objections. */
+ if (n->bcast)
+ {
+ /* broadcast method: implicit acceptance of the name registration
+ by not receiving any objections. */
- /* IMPORTANT: see response_name_reg() */
+ /* IMPORTANT: see response_name_reg() */
- name_register_work(d,n->name.name,n->name.name_type,
- n->nb_flags, n->ttl, n->reply_to_ip, n->bcast);
- }
- else if (n->num_msgs == 0)
- {
- /* received no response. rfc1001.txt states that after retrying,
- we should assume the WINS server is dead, and fall back to
- broadcasting (see bits about M nodes: can't find any right
- now) */
+ name_register_work(d,n->name.name,n->name.name_type,
+ n->nb_flags, n->ttl, n->reply_to_ip, n->bcast);
+ }
+ else
+ {
+ /* received no response. rfc1001.txt states that after retrying,
+ we should assume the WINS server is dead, and fall back to
+ broadcasting (see bits about M nodes: can't find any right
+ now) */
- DEBUG(1,("WINS server did not respond to name registration!\n"));
- /* XXXX whoops. we have problems. must deal with this */
+ DEBUG(1,("WINS server did not respond to name registration!\n"));
+ /* XXXX whoops. we have problems. must deal with this */
+ }
}
break;
}
diff --git a/source3/nameservreply.c b/source3/nameservreply.c
index df30e4ac41..544cbc62b4 100644
--- a/source3/nameservreply.c
+++ b/source3/nameservreply.c
@@ -127,9 +127,9 @@ void reply_name_release(struct packet_struct *p)
}
if (bcast)
- search &= FIND_LOCAL;
+ search |= FIND_LOCAL;
else
- search &= FIND_WINS;
+ search |= FIND_WINS;
n = find_name_search(&d, &nmb->question.question_name,
search, ip);
@@ -183,7 +183,7 @@ void reply_name_reg(struct packet_struct *p)
putip((char *)&from_ip,&nmb->additional->rdata[2]);
ip = from_ip;
- DEBUG(3,("Name registration for name %s at %s\n",
+ DEBUG(3,("Name registration for name %s at %s - ",
namestr(question),inet_ntoa(ip)));
if (group)
@@ -201,15 +201,16 @@ void reply_name_reg(struct packet_struct *p)
}
if (bcast)
- search &= FIND_LOCAL;
+ search |= FIND_LOCAL;
else
- search &= FIND_WINS;
+ search |= FIND_WINS;
/* see if the name already exists */
n = find_name_search(&d, question, search, from_ip);
if (n)
{
+ DEBUG(3,("found\n"));
if (!group) /* unique names */
{
if (n->source == SELF || NAME_GROUP(n->ip_flgs[0].nb_flags))
@@ -259,6 +260,7 @@ void reply_name_reg(struct packet_struct *p)
}
else
{
+ DEBUG(3,("not found\n"));
/* add the name to our name/subnet, or WINS, database */
n = add_netbios_entry(d,qname,qname_type,nb_flags,ttl,REGISTER,ip,
True,!bcast);
@@ -458,10 +460,8 @@ void reply_name_status(struct packet_struct *p)
reply_netbios_packet(p,nmb->header.name_trn_id,
0,NMB_STATUS,0,True,
&nmb->question.question_name,
- nmb->question.question_type,
- nmb->question.question_class,
- 0,
- rdata,PTR_DIFF(buf,rdata));
+ 0x21, 0x01,
+ 0, rdata,PTR_DIFF(buf,rdata));
}
@@ -549,8 +549,8 @@ void reply_name_query(struct packet_struct *p)
n = find_name_search(&d, question, search, p->ip);
/* it is a name that already failed DNS lookup or it's expired */
- if (n->source == DNSFAIL ||
- (n->death_time && n->death_time < p->timestamp))
+ if (n && (n->source == DNSFAIL ||
+ (n->death_time && n->death_time < p->timestamp)))
{
success = False;
}
@@ -625,8 +625,7 @@ void reply_name_query(struct packet_struct *p)
reply_netbios_packet(p,nmb->header.name_trn_id,
rcode,NMB_QUERY,0,True,
&nmb->question.question_name,
- nmb->question.question_type,
- nmb->question.question_class,
+ 0x20, 0x01,
ttl,
rdata, success ? 6 : 0);
}
diff --git a/source3/nameservresp.c b/source3/nameservresp.c
index 91f915b760..cc117f9b15 100644
--- a/source3/nameservresp.c
+++ b/source3/nameservresp.c
@@ -46,12 +46,12 @@ extern struct in_addr ipzero;
response for a reg release received. samba has asked a WINS server if it
could release a name.
**************************************************************************/
-static void response_name_release(struct subnet_record *d,
- struct packet_struct *p)
+static void response_name_release(struct nmb_name *ans_name,
+ struct subnet_record *d, struct packet_struct *p)
{
struct nmb_packet *nmb = &p->packet.nmb;
- char *name = nmb->question.question_name.name;
- int type = nmb->question.question_name.name_type;
+ char *name = ans_name->name;
+ int type = ans_name->name_type;
DEBUG(4,("response name release received\n"));
@@ -70,14 +70,12 @@ static void response_name_release(struct subnet_record *d,
else
{
DEBUG(2,("name release for different ip! %s %s\n",
- inet_ntoa(found_ip),
- namestr(&nmb->question.question_name)));
+ inet_ntoa(found_ip), namestr(ans_name)));
}
}
else
{
- DEBUG(2,("name release for %s rejected!\n",
- namestr(&nmb->question.question_name)));
+ DEBUG(2,("name release for %s rejected!\n", namestr(ans_name)));
/* XXXX PANIC! what to do if it's one of samba's own names? */
@@ -91,12 +89,13 @@ static void response_name_release(struct subnet_record *d,
/****************************************************************************
response for a reg request received
**************************************************************************/
-static void response_name_reg(struct subnet_record *d, struct packet_struct *p)
+static void response_name_reg(struct nmb_name *ans_name,
+ struct subnet_record *d, struct packet_struct *p)
{
struct nmb_packet *nmb = &p->packet.nmb;
- char *name = nmb->question.question_name.name;
- int type = nmb->question.question_name.name_type;
BOOL bcast = nmb->header.nm_flags.bcast;
+ char *name = ans_name->name;
+ int type = ans_name->name_type;
DEBUG(4,("response name registration received!\n"));
@@ -114,8 +113,7 @@ static void response_name_reg(struct subnet_record *d, struct packet_struct *p)
}
else
{
- DEBUG(1,("name registration for %s rejected!\n",
- namestr(&nmb->question.question_name)));
+ DEBUG(2,("name registration for %s rejected!\n", namestr(ans_name)));
/* oh dear. we have problems. possibly unbecome a master browser. */
name_unregister_work(d,name,type);
@@ -527,7 +525,7 @@ void debug_state_type(int state)
(responses for certain types of operations are only expected from one host)
****************************************************************************/
static BOOL response_problem_check(struct response_record *n,
- struct nmb_packet *nmb, char *qname)
+ struct nmb_packet *nmb, char *ans_name)
{
switch (nmb->answers->rr_type)
{
@@ -584,7 +582,7 @@ static BOOL response_problem_check(struct response_record *n,
case NAME_QUERY_SRV_CHK:
case NAME_QUERY_MST_CHK:
{
- if (!strequal(qname,n->name.name))
+ if (!strequal(ans_name,n->name.name))
{
/* one subnet, one master browser per workgroup */
/* XXXX force an election? */
@@ -694,13 +692,13 @@ static void response_process(struct subnet_record *d, struct packet_struct *p,
{
case NAME_RELEASE:
{
- response_name_release(d, p);
+ response_name_release(ans_name, d, p);
break;
}
case NAME_REGISTER:
{
- response_name_reg(d, p);
+ response_name_reg(ans_name, d, p);
break;
}
@@ -763,9 +761,7 @@ static void response_process(struct subnet_record *d, struct packet_struct *p,
void response_netbios_packet(struct packet_struct *p)
{
struct nmb_packet *nmb = &p->packet.nmb;
- struct nmb_name *question = &nmb->question.question_name;
struct nmb_name *ans_name = NULL;
- char *qname = question->name;
BOOL bcast = nmb->header.nm_flags.bcast;
struct response_record *n;
struct subnet_record *d = NULL;
@@ -809,7 +805,7 @@ void response_netbios_packet(struct packet_struct *p)
debug_state_type(n->state);
/* problem checking: multiple responses etc */
- if (response_problem_check(n, nmb, qname))
+ if (response_problem_check(n, nmb, ans_name->name))
return;
/* now deal with the current state */
diff --git a/source3/namework.c b/source3/namework.c
index 80183dac84..f4a9113cea 100644
--- a/source3/namework.c
+++ b/source3/namework.c
@@ -175,8 +175,7 @@ BOOL same_context(struct dgram_packet *dgram)
static void process_announce(struct packet_struct *p,uint16 command,char *buf)
{
struct dgram_packet *dgram = &p->packet.dgram;
- struct in_addr ip = dgram->header.source_ip;
- struct subnet_record *d = find_subnet(ip);
+ struct subnet_record *d = find_subnet(p->ip);
int update_count = CVAL(buf,0);
int ttl = IVAL(buf,1)/1000;
@@ -213,7 +212,7 @@ static void process_announce(struct packet_struct *p,uint16 command,char *buf)
dgram->dest_name.name_type != 0x1))
{
DEBUG(0,("Announce(%d) from %s should be __MSBROWSE__(1) not %s\n",
- command, inet_ntoa(ip), namestr(&dgram->dest_name)));
+ command, inet_ntoa(p->ip), namestr(&dgram->dest_name)));
return;
}
@@ -243,6 +242,9 @@ static void process_announce(struct packet_struct *p,uint16 command,char *buf)
dgram->dest_name.name_type == 0x1e))
add = True;
+ DEBUG(4,("search for workgroup: %s (add? %s)\n",
+ work_name, BOOLSTR(add)));
+
if (!(work = find_workgroupstruct(d, work_name,add)))
return;
@@ -265,7 +267,7 @@ static void process_announce(struct packet_struct *p,uint16 command,char *buf)
if (command == ANN_LocalMasterAnnouncement)
{
add_browser_entry(serv_name,dgram->dest_name.name_type,
- work->work_group,30,ip,True);
+ work->work_group,30,p->ip,True);
}
}
@@ -275,27 +277,25 @@ static void process_announce(struct packet_struct *p,uint16 command,char *buf)
static void process_master_announce(struct packet_struct *p,char *buf)
{
struct dgram_packet *dgram = &p->packet.dgram;
- struct in_addr ip = dgram->header.source_ip;
- struct subnet_record *d = find_subnet(ip);
- struct subnet_record *mydomain = find_subnet(*iface_bcast(ip));
+ struct subnet_record *d = find_subnet(p->ip);
char *name = buf;
struct work_record *work;
name[15] = 0;
- DEBUG(3,("Master Announce from %s (%s)\n",name,inet_ntoa(ip)));
+ DEBUG(3,("Master Announce from %s (%s)\n",name,inet_ntoa(p->ip)));
if (same_context(dgram)) return;
- if (!d || !mydomain) return;
+ if (!d) return;
if (!lp_domain_master()) return;
- for (work = mydomain->workgrouplist; work; work = work->next)
+ for (work = d->workgrouplist; work; work = work->next)
{
if (AM_MASTER(work))
{
/* merge browse lists with them */
- add_browser_entry(name,0x1b, work->work_group,30,ip,True);
+ add_browser_entry(name,0x1b, work->work_group,30,p->ip,True);
}
}
}
@@ -316,13 +316,12 @@ static void process_master_announce(struct packet_struct *p,char *buf)
static void process_rcv_backup_list(struct packet_struct *p,char *buf)
{
struct dgram_packet *dgram = &p->packet.dgram;
- struct in_addr ip = dgram->header.source_ip;
int count = CVAL(buf,0);
uint32 info = IVAL(buf,1); /* XXXX caller's incremental info */
char *buf1;
DEBUG(3,("Receive Backup ack for %s from %s total=%d info=%d\n",
- namestr(&dgram->dest_name), inet_ntoa(ip),
+ namestr(&dgram->dest_name), inet_ntoa(p->ip),
count, info));
if (same_context(dgram)) return;
@@ -336,7 +335,7 @@ static void process_rcv_backup_list(struct packet_struct *p,char *buf)
/* struct subnet_record *d; */
DEBUG(4,("Searching for backup browser %s at %s...\n",
- buf1, inet_ntoa(ip)));
+ buf1, inet_ntoa(p->ip)));
/* XXXX assume name is a DNS name NOT a netbios name. a more complete
approach is to use reply_name_query functionality to find the name */