diff options
-rw-r--r-- | source3/namedbname.c | 7 | ||||
-rw-r--r-- | source3/namedbsubnet.c | 17 | ||||
-rw-r--r-- | source3/namepacket.c | 103 | ||||
-rw-r--r-- | source3/nameresp.c | 33 | ||||
-rw-r--r-- | source3/nameservreply.c | 25 | ||||
-rw-r--r-- | source3/nameservresp.c | 36 | ||||
-rw-r--r-- | source3/namework.c | 27 |
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 */ |