diff options
Diffstat (limited to 'source3/nameresp.c')
-rw-r--r-- | source3/nameresp.c | 381 |
1 files changed, 176 insertions, 205 deletions
diff --git a/source3/nameresp.c b/source3/nameresp.c index a9422116fb..7fcb41e79f 100644 --- a/source3/nameresp.c +++ b/source3/nameresp.c @@ -35,30 +35,15 @@ extern pstring scope; extern struct in_addr ipzero; extern struct in_addr ipgrp; -uint16 name_trn_id=0; - - -/*************************************************************************** - updates the unique transaction identifier - **************************************************************************/ -void update_name_trn_id(void) -{ - if (!name_trn_id) - { - name_trn_id = (time(NULL)%(unsigned)0x7FFF) + (getpid()%(unsigned)100); - } - name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF; -} - /*************************************************************************** deals with an entry before it dies **************************************************************************/ static void dead_netbios_entry(struct subnet_record *d, - struct response_record *n) + struct response_record *n) { DEBUG(3,("Removing dead netbios entry for %s %s (num_msgs=%d)\n", - inet_ntoa(n->send_ip), namestr(&n->name), n->num_msgs)); + inet_ntoa(n->send_ip), namestr(&n->name), n->num_msgs)); debug_state_type(n->state); @@ -66,118 +51,118 @@ static void dead_netbios_entry(struct subnet_record *d, { case NAME_QUERY_CONFIRM: { - if (!lp_wins_support()) return; /* only if we're a WINS server */ + if (!lp_wins_support()) return; /* only if we're a WINS server */ - if (n->num_msgs == 0) + if (n->num_msgs == 0) { - /* oops. name query had no response. check that the name is - unique and then remove it from our WINS database */ - - /* IMPORTANT: see query_refresh_names() */ - - if ((!NAME_GROUP(n->reply.nb_flags))) - { - struct subnet_record *d1 = find_subnet(ipgrp); - if (d1) - { - /* remove the name that had been registered with us, - and we're now getting no response when challenging. - see rfc1001.txt 15.5.2 - */ - remove_netbios_name(d1, n->name.name, n->name.name_type, - REGISTER, n->send_ip); - } - } - } - break; - } - - case NAME_QUERY_MST_CHK: - { - /* if no response received, the master browser must have gone - down on that subnet, without telling anyone. */ - - /* IMPORTANT: see response_netbios_packet() */ - - if (n->num_msgs == 0) - browser_gone(n->name.name, n->send_ip); - break; + /* oops. name query had no response. check that the name is + unique and then remove it from our WINS database */ + + /* IMPORTANT: see query_refresh_names() */ + + if ((!NAME_GROUP(n->nb_flags))) + { + struct subnet_record *d1 = find_subnet(ipgrp); + if (d1) + { + /* remove the name that had been registered with us, + and we're now getting no response when challenging. + see rfc1001.txt 15.5.2 + */ + remove_netbios_name(d1, n->name.name, n->name.name_type, + REGISTER, n->send_ip); + } + } + } + break; } - case NAME_RELEASE: - { - /* if no response received, it must be OK for us to release the - name. nobody objected (including a potentially dead or deaf - WINS server) */ - - /* IMPORTANT: see response_name_release() */ - - if (ismyip(n->send_ip)) - { - name_unregister_work(d,n->name.name,n->name.name_type); - } - if (!n->bcast) - { - DEBUG(0,("WINS server did not respond to name release!\n")); + case NAME_QUERY_MST_CHK: + { + /* if no response received, the master browser must have gone + down on that subnet, without telling anyone. */ + + /* IMPORTANT: see response_netbios_packet() */ + + if (n->num_msgs == 0) + browser_gone(n->name.name, n->send_ip); + break; + } + + case NAME_RELEASE: + { + /* if no response received, it must be OK for us to release the + name. nobody objected (including a potentially dead or deaf + WINS server) */ + + /* IMPORTANT: see response_name_release() */ + + if (ismyip(n->send_ip)) + { + name_unregister_work(d,n->name.name,n->name.name_type); + } + if (!n->bcast) + { + DEBUG(0,("WINS server did not respond to name release!\n")); /* XXXX whoops. we have problems. must deal with this */ - } - break; - } - - case NAME_REGISTER_CHALLENGE: - { - /* name challenge: no reply. we can reply to the person that - wanted the unique name and tell them that they can have it - */ - - add_name_respond(d,n->fd,d->myip, n->response_id ,&n->name, - n->reply.nb_flags, GET_TTL(0), - n->reply.ip, False, n->reply.ip); - - if (!n->bcast) - { - DEBUG(1,("WINS server did not respond to name registration!\n")); + } + break; + } + + case NAME_REGISTER_CHALLENGE: + { + /* name challenge: no reply. we can reply to the person that + wanted the unique name and tell them that they can have it + */ + + add_name_respond(d,n->fd,d->myip, n->response_id ,&n->name, + n->nb_flags, GET_TTL(0), + n->reply_to_ip, False, n->reply_to_ip); + + if (!n->bcast) + { + DEBUG(1,("WINS server did not respond to name registration!\n")); /* XXXX whoops. we have problems. must deal with this */ - } + } break; - } - - case NAME_REGISTER: - { - /* if no response received, and we are using a broadcast registration - method, it must be OK for us to register the name: nobody objected - on that subnet. if we are using a WINS server, then the WINS - server must be dead or deaf. - */ - if (n->bcast) - { - /* broadcast method: implicit acceptance of the name registration - by not receiving any objections. */ - - /* IMPORTANT: see response_name_reg() */ - - name_register_work(d,n->token,n->name.name,n->name.name_type, - &n->reply, n->ttl, n->reply.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 + } + + case NAME_REGISTER: + { + /* if no response received, and we are using a broadcast registration + method, it must be OK for us to register the name: nobody objected + on that subnet. if we are using a WINS server, then the WINS + server must be dead or deaf. + */ + if (n->bcast) + { + /* broadcast method: implicit acceptance of the name registration + by not receiving any objections. */ + + /* 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 + { + /* 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")); + + DEBUG(1,("WINS server did not respond to name registration!\n")); /* XXXX whoops. we have problems. must deal with this */ - } - break; - } - - default: - { - /* nothing to do but delete the dead expected-response structure */ - /* this is normal. */ - break; - } + } + break; + } + + default: + { + /* nothing to do but delete the dead expected-response structure */ + /* this is normal. */ + break; + } } } @@ -199,33 +184,33 @@ void expire_netbios_response_entries() for (n = d->responselist; n; n = nextn) { - nextn = n->next; + nextn = n->next; if (n->repeat_time <= time(NULL)) - { - if (n->repeat_count > 0) - { - /* resend the entry */ - initiate_netbios_packet(n->response_id, n->fd, n->quest_type, - n->name.name, n->name.name_type, - n->reply.nb_flags, n->bcast, n->recurse, n->send_ip); + { + if (n->repeat_count > 0) + { + /* resend the entry */ + initiate_netbios_packet(&n->response_id, n->fd, n->quest_type, + n->name.name, n->name.name_type, + n->nb_flags, n->bcast, n->recurse, n->send_ip); n->repeat_time += n->repeat_interval; /* XXXX ms needed */ n->repeat_count--; - } - else - { + } + else + { DEBUG(4,("timeout response %d for %s %s\n", - n->response_id, namestr(&n->name), + n->response_id, namestr(&n->name), inet_ntoa(n->send_ip))); - dead_netbios_entry (d,n); /* process the non-response */ + dead_netbios_entry (d,n); /* process the non-response */ remove_response_record(d,n); /* remove the non-response */ - continue; - } - } + continue; + } + } } } } @@ -236,56 +221,44 @@ void expire_netbios_response_entries() name server instead, if it exists. if wins is false, and there has been no WINS server specified, the packet will NOT be sent. ****************************************************************************/ -void queue_netbios_pkt_wins(struct subnet_record *d, - int fd,int quest_type,enum state_type state, - int token, char *name,int name_type,int nb_flags, time_t ttl, - int server_type, char *my_name, char *my_comment, - BOOL bcast,BOOL recurse, - struct in_addr send_ip, struct in_addr reply_to_ip) +struct response_record *queue_netbios_pkt_wins(struct subnet_record *d, + int fd,int quest_type,enum state_type state, + char *name,int name_type,int nb_flags, time_t ttl, + int server_type, char *my_name, char *my_comment, + BOOL bcast,BOOL recurse, + struct in_addr send_ip, struct in_addr reply_to_ip) { - /* XXXX note: please see rfc1001.txt section 10 for details on this - function: it is currently inappropriate to use this - it will do - for now - once there is a clarification of B, M and P nodes and - which one samba is supposed to be - */ + /* XXXX note: please see rfc1001.txt section 10 for details on this + function: it is currently inappropriate to use this - it will do + for now - once there is a clarification of B, M and P nodes and + which one samba is supposed to be + */ - if ((!lp_wins_support()) && (*lp_wins_server())) + if ((!lp_wins_support()) && (*lp_wins_server())) { - /* samba is not a WINS server, and we are using a WINS server */ - struct in_addr wins_ip; - wins_ip = *interpret_addr2(lp_wins_server()); - - if (!zero_ip(wins_ip)) - { - bcast = False; - send_ip = wins_ip; - } - else - { - /* oops. smb.conf's wins server parameter MUST be a host_name - or an ip_address. */ - DEBUG(0,("invalid smb.conf parameter 'wins server'\n")); - } - } - - if (zero_ip(send_ip)) - { - /* doing a netbios query to samba as a WINS server, internally */ - if (lp_wins_support()) - { - DEBUG(4,("queue netbios packet with ourselves...\n")); - bcast = False; - } + /* samba is not a WINS server, and we are using a WINS server */ + struct in_addr wins_ip; + wins_ip = *interpret_addr2(lp_wins_server()); + + if (!zero_ip(wins_ip)) + { + bcast = False; + send_ip = wins_ip; + } else - { - return; - } + { + /* oops. smb.conf's wins server parameter MUST be a host_name + or an ip_address. */ + DEBUG(0,("invalid smb.conf parameter 'wins server'\n")); + } } - - queue_netbios_packet(d,fd, quest_type, state, - token, name, name_type, nb_flags, ttl, + + if (zero_ip(send_ip)) return NULL; + + return queue_netbios_packet(d,fd, quest_type, state, + name, name_type, nb_flags, ttl, server_type,my_name,my_comment, - bcast, recurse, send_ip, reply_to_ip); + bcast, recurse, send_ip, reply_to_ip); } @@ -295,37 +268,35 @@ void queue_netbios_pkt_wins(struct subnet_record *d, master browsers (WORKGROUP(1d or 1b) or __MSBROWSE__(1)) to get complete lists across a wide area network ****************************************************************************/ -void queue_netbios_packet(struct subnet_record *d, - int fd,int quest_type,enum state_type state, - int token, char *name, int name_type,int nb_flags, time_t ttl, - int server_type, char *my_name, char *my_comment, - BOOL bcast,BOOL recurse, - struct in_addr send_ip, struct in_addr reply_to_ip) +struct response_record *queue_netbios_packet(struct subnet_record *d, + int fd,int quest_type,enum state_type state,char *name, + int name_type,int nb_flags, time_t ttl, + int server_type, char *my_name, char *my_comment, + BOOL bcast,BOOL recurse, + struct in_addr send_ip, struct in_addr reply_to_ip) { struct in_addr wins_ip = ipgrp; struct response_record *n; + uint16 id = 0xffff; /* ha ha. no. do NOT broadcast to 255.255.255.255: it's a pseudo address */ - if (ip_equal(wins_ip, send_ip)) return; - - update_name_trn_id(); - - /* queue the response expected because if we do a query with an ip - of zero, we are expecting to hear from ourself immediately */ - if ((n = make_response_queue_record(state, name_trn_id, fd, quest_type, - token, name, name_type, nb_flags, ttl, - server_type, my_name, my_comment, - bcast, recurse, send_ip, reply_to_ip))) - { - add_response_record(d,n); - } + if (ip_equal(wins_ip, send_ip)) return NULL; - if (!initiate_netbios_packet(name_trn_id, fd, quest_type, name, name_type, - nb_flags, bcast, recurse, send_ip)) - { - /* packet wasn't sent - not expecting a response */ + initiate_netbios_packet(&id, fd, quest_type, name, name_type, + nb_flags, bcast, recurse, send_ip); + + if (id == 0xffff) { DEBUG(4,("did not initiate netbios packet: %s\n", inet_ntoa(send_ip))); - remove_response_record(d, n); - return; + return NULL; } + + if ((n = make_response_queue_record(state,id,fd, + quest_type,name,name_type,nb_flags,ttl, + server_type,my_name, my_comment, + bcast,recurse,send_ip,reply_to_ip))) + { + add_response_record(d,n); + return n; + } + return NULL; } |