summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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 */