nmbd/nmbd_nameregister.c

ソースコードを見る。

関数

static void wins_next_registration (struct response_record *rrec)
static void register_name_response (struct subnet_record *subrec, struct response_record *rrec, struct packet_struct *p)
static void wins_registration_timeout (struct subnet_record *subrec, struct response_record *rrec)
static void register_name_timeout_response (struct subnet_record *subrec, struct response_record *rrec)
static void multihomed_register_one (struct nmb_name *nmbname, uint16 nb_flags, register_name_success_function success_fn, register_name_fail_function fail_fn, struct in_addr ip, const char *tag)
static void multihomed_register_name (struct nmb_name *nmbname, uint16 nb_flags, register_name_success_function success_fn, register_name_fail_function fail_fn)
void register_name (struct subnet_record *subrec, const char *name, int type, uint16 nb_flags, register_name_success_function success_fn, register_name_fail_function fail_fn, struct userdata_struct *userdata)
void wins_refresh_name (struct name_record *namerec)


関数

static void wins_next_registration ( struct response_record rrec  )  [static]

nmbd_nameregister.c347 行で定義されています。

参照先 nmb_packet::additionaluserdata_struct::dataget_nb_flags()nmb_packet::headermultihomed_register_one()subnet_record::myippacket_struct::nmbnmb_packet::opcodepacket_struct::packetresponse_record::packetnmb_packet::questionnmb_packet::question_namequeue_wins_refresh()res_rec::rdataregister_name_response()register_name_timeout_response()response_record::userdata.

参照元 register_name_response()wins_registration_timeout().

00348 {
00349         struct nmb_packet *sent_nmb = &rrec->packet->packet.nmb;
00350         struct nmb_name *nmbname = &sent_nmb->question.question_name;
00351         uint16 nb_flags = get_nb_flags(sent_nmb->additional->rdata);
00352         struct userdata_struct *userdata = rrec->userdata;
00353         const char *tag;
00354         struct in_addr last_ip;
00355         struct subnet_record *subrec;
00356 
00357         putip(&last_ip,&sent_nmb->additional->rdata[2]);
00358 
00359         if (!userdata) {
00360                 /* it wasn't multi-homed */
00361                 return;
00362         }
00363 
00364         tag = (const char *)userdata->data;
00365 
00366         for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
00367                 if (ip_equal(last_ip, subrec->myip)) {
00368                         subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec);
00369                         break;
00370                 }
00371         }
00372 
00373         if (!subrec) {
00374                 /* no more to do! */
00375                 return;
00376         }
00377 
00378         switch (sent_nmb->header.opcode) {
00379         case NMB_NAME_MULTIHOMED_REG_OPCODE:
00380                 multihomed_register_one(nmbname, nb_flags, NULL, NULL, subrec->myip, tag);
00381                 break;
00382         case NMB_NAME_REFRESH_OPCODE_8:
00383                 queue_wins_refresh(nmbname, 
00384                                    register_name_response,
00385                                    register_name_timeout_response,
00386                                    nb_flags, subrec->myip, tag);
00387                 break;
00388         }
00389 }

static void register_name_response ( struct subnet_record subrec,
struct response_record rrec,
struct packet_struct p 
) [static]

nmbd_nameregister.c34 行で定義されています。

参照先 nmb_packet::additionalnmb_packet::answersnmb_packet::bcastresponse_record::fail_fnget_nb_flags()nmb_packet::headerpacket_struct::iplp_workgroup()nmb_name::namenmb_name::name_typenmb_packet::nm_flagspacket_struct::nmbnmb_name_equal()nmb_namestr()response_record::num_msgsnmb_packet::opcoderesponse_record::packetpacket_struct::packetpull_ascii_nstring()nmb_packet::questionnmb_packet::question_namenmb_packet::rcoderes_rec::rdataremove_response_record()response_record::repeat_countresponse_record::repeat_timeres_rec::rr_namestandard_fail_register()standard_success_register()strequal()subnet_record::subnet_nameresponse_record::success_fnpacket_struct::timestampres_rec::ttlunicast_subnetresponse_record::userdatawins_next_registration()wins_srv_alive().

参照元 multihomed_register_one()register_name()wins_next_registration()wins_refresh_name().

00036 {
00037         /* 
00038          * If we are registering broadcast, then getting a response is an
00039          * error - we do not have the name. If we are registering unicast,
00040          * then we expect to get a response.
00041          */
00042 
00043         struct nmb_packet *nmb = &p->packet.nmb;
00044         BOOL bcast = nmb->header.nm_flags.bcast;
00045         BOOL success = True;
00046         struct nmb_name *question_name = &rrec->packet->packet.nmb.question.question_name;
00047         struct nmb_name *answer_name = &nmb->answers->rr_name;
00048         struct nmb_packet *sent_nmb = &rrec->packet->packet.nmb;
00049         int ttl = 0;
00050         uint16 nb_flags = 0;
00051         struct in_addr register_ip;
00052         fstring reg_name;
00053         
00054         putip(&register_ip,&sent_nmb->additional->rdata[2]);
00055         fstrcpy(reg_name, inet_ntoa(register_ip));
00056         
00057         if (subrec == unicast_subnet) {
00058                 /* we know that this wins server is definately alive - for the moment! */
00059                 wins_srv_alive(rrec->packet->ip, register_ip);
00060         }
00061 
00062         /* Sanity check. Ensure that the answer name in the incoming packet is the
00063            same as the requested name in the outgoing packet. */
00064 
00065         if(!question_name || !answer_name) {
00066                 DEBUG(0,("register_name_response: malformed response (%s is NULL).\n",
00067                          question_name ? "question_name" : "answer_name" ));
00068                 return;
00069         }
00070 
00071         if(!nmb_name_equal(question_name, answer_name)) {
00072                 DEBUG(0,("register_name_response: Answer name %s differs from question name %s.\n", 
00073                          nmb_namestr(answer_name), nmb_namestr(question_name)));
00074                 return;
00075         }
00076 
00077         if(bcast) {
00078                 /*
00079                  * Special hack to cope with old Samba nmbd's.
00080                  * Earlier versions of Samba (up to 1.9.16p11) respond 
00081                  * to a broadcast name registration of WORKGROUP<1b> when 
00082                  * they should not. Hence, until these versions are gone, 
00083                  * we should treat such errors as success for this particular
00084                  * case only. jallison@whistle.com.
00085                  */
00086                 
00087 #if 1 /* OLD_SAMBA_SERVER_HACK */
00088                 unstring ans_name;
00089                 pull_ascii_nstring(ans_name, sizeof(ans_name), answer_name->name);
00090                 if((nmb->header.rcode == ACT_ERR) && strequal(lp_workgroup(), ans_name) &&
00091                    (answer_name->name_type == 0x1b)) {
00092                         /* Pretend we did not get this. */
00093                         rrec->num_msgs--;
00094 
00095                         DEBUG(5,("register_name_response: Ignoring broadcast response to registration of name %s due to old Samba server bug.\n", 
00096                                  nmb_namestr(answer_name)));
00097                         return;
00098                 }
00099 #endif /* OLD_SAMBA_SERVER_HACK */
00100 
00101                 /* Someone else has the name. Log the problem. */
00102                 DEBUG(1,("register_name_response: Failed to register name %s IP %s on subnet %s via broadcast. Error code was %d. Reject came from IP %s\n", 
00103                          nmb_namestr(answer_name), 
00104                          reg_name,
00105                          subrec->subnet_name, nmb->header.rcode, inet_ntoa(p->ip)));
00106                 success = False;
00107         } else {
00108                 /* Unicast - check to see if the response allows us to have the name. */
00109                 if (nmb->header.opcode == NMB_WACK_OPCODE) {
00110                         /* WINS server is telling us to wait. Pretend we didn't get
00111                            the response but don't send out any more register requests. */
00112 
00113                         DEBUG(5,("register_name_response: WACK from WINS server %s in registering name %s IP %s\n", 
00114                                  inet_ntoa(p->ip), nmb_namestr(answer_name), reg_name));
00115 
00116                         rrec->repeat_count = 0;
00117                         /* How long we should wait for. */
00118                         rrec->repeat_time = p->timestamp + nmb->answers->ttl;
00119                         rrec->num_msgs--;
00120                         return;
00121                 } else if (nmb->header.rcode != 0) {
00122                         /* Error code - we didn't get the name. */
00123                         success = False;
00124 
00125                         DEBUG(0,("register_name_response: %sserver at IP %s rejected our name registration of %s IP %s with error code %d.\n", 
00126                                  subrec==unicast_subnet?"WINS ":"",
00127                                  inet_ntoa(p->ip), 
00128                                  nmb_namestr(answer_name), 
00129                                  reg_name,
00130                                  nmb->header.rcode));
00131                 } else {
00132                         success = True;
00133                         /* Get the data we need to pass to the success function. */
00134                         nb_flags = get_nb_flags(nmb->answers->rdata);
00135                         ttl = nmb->answers->ttl;
00136 
00137                         /* send off a registration for the next IP, if any */
00138                         wins_next_registration(rrec);
00139                 }
00140         } 
00141 
00142         DEBUG(5,("register_name_response: %s in registering %sname %s IP %s with %s.\n",
00143                  success ? "success" : "failure", 
00144                  subrec==unicast_subnet?"WINS ":"",
00145                  nmb_namestr(answer_name), 
00146                  reg_name,
00147                  inet_ntoa(rrec->packet->ip)));
00148 
00149         if(success) {
00150                 /* Enter the registered name into the subnet name database before calling
00151                    the success function. */
00152                 standard_success_register(subrec, rrec->userdata, answer_name, nb_flags, ttl, register_ip);
00153                 if( rrec->success_fn)
00154                         (*(register_name_success_function)rrec->success_fn)(subrec, rrec->userdata, answer_name, nb_flags, ttl, register_ip);
00155         } else {
00156                 struct nmb_name qname = *question_name;
00157                 if( rrec->fail_fn)
00158                         (*(register_name_fail_function)rrec->fail_fn)(subrec, rrec, question_name);
00159                 /* Remove the name. */
00160                 standard_fail_register( subrec, &qname);
00161         }
00162 
00163         /* Ensure we don't retry. */
00164         remove_response_record(subrec, rrec);
00165 }

static void wins_registration_timeout ( struct subnet_record subrec,
struct response_record rrec 
) [static]

nmbd_nameregister.c171 行で定義されています。

参照先 nmb_packet::additionaluserdata_struct::dataget_nb_flags()response_record::in_expiration_processingpacket_struct::ippacket_struct::nmbnmb_namestr()packet_struct::packetresponse_record::packetnmb_packet::questionnmb_packet::question_nameres_rec::rdataremove_response_record()response_record::repeat_countresponse_record::repeat_timestandard_success_register()response_record::success_fnres_rec::ttlresponse_record::userdatawins_next_registration()wins_srv_died()wins_srv_ip_tag()wins_srv_is_dead().

参照元 register_name_timeout_response().

00173 {
00174         struct userdata_struct *userdata = rrec->userdata;
00175         struct nmb_packet *sent_nmb = &rrec->packet->packet.nmb;
00176         struct nmb_name *nmbname = &sent_nmb->question.question_name;
00177         struct in_addr register_ip;
00178         fstring src_addr;
00179 
00180         putip(&register_ip,&sent_nmb->additional->rdata[2]);
00181 
00182         fstrcpy(src_addr, inet_ntoa(register_ip));
00183 
00184         DEBUG(2,("wins_registration_timeout: WINS server %s timed out registering IP %s\n", 
00185                  inet_ntoa(rrec->packet->ip), src_addr));
00186 
00187         /* mark it temporarily dead for this source address */
00188         wins_srv_died(rrec->packet->ip, register_ip);
00189 
00190         /* if we have some userdata then use that to work out what
00191            wins server to try next */
00192         if (userdata) {
00193                 const char *tag = (const char *)userdata->data;
00194 
00195                 /* try the next wins server in our failover list for
00196                    this tag */
00197                 rrec->packet->ip = wins_srv_ip_tag(tag, register_ip);
00198         }
00199 
00200         /* if we have run out of wins servers for this tag then they
00201            must all have timed out. We treat this as *success*, not
00202            failure, and go into our standard name refresh mode. This
00203            copes with all the wins servers being down */
00204         if (wins_srv_is_dead(rrec->packet->ip, register_ip)) {
00205                 uint16 nb_flags = get_nb_flags(sent_nmb->additional->rdata);
00206                 int ttl = sent_nmb->additional->ttl;
00207 
00208                 standard_success_register(subrec, userdata, nmbname, nb_flags, ttl, register_ip);
00209                 if(rrec->success_fn) {
00210                         (*(register_name_success_function)rrec->success_fn)(subrec, 
00211                                                                             rrec->userdata, 
00212                                                                             nmbname, 
00213                                                                             nb_flags, 
00214                                                                             ttl, 
00215                                                                             register_ip);
00216                 }
00217 
00218                 /* send off a registration for the next IP, if any */
00219                 wins_next_registration(rrec);
00220 
00221                 /* don't need to send this packet any more */
00222                 remove_response_record(subrec, rrec);
00223                 return;
00224         }
00225         
00226         /* we will be moving to the next WINS server for this group,
00227            send it immediately */
00228         rrec->repeat_count = 2;
00229         rrec->repeat_time = time(NULL) + 1;
00230         rrec->in_expiration_processing = False;
00231 
00232         DEBUG(6,("Retrying register of name %s IP %s with WINS server %s\n",
00233                  nmb_namestr(nmbname), src_addr, inet_ntoa(rrec->packet->ip)));
00234 
00235         /* notice that we don't remove the response record. This keeps
00236            us trying to register with each of our failover wins servers */
00237 }

static void register_name_timeout_response ( struct subnet_record subrec,
struct response_record rrec 
) [static]

nmbd_nameregister.c243 行で定義されています。

参照先 nmb_packet::additionalnmb_packet::bcastresponse_record::fail_fnget_nb_flags()nmb_packet::headernmb_packet::nm_flagspacket_struct::nmbnmb_namestr()response_record::num_msgspacket_struct::packetresponse_record::packetnmb_packet::questionnmb_packet::question_nameres_rec::rdataremove_response_record()standard_fail_register()standard_success_register()subnet_record::subnet_nameresponse_record::success_fnres_rec::ttlresponse_record::userdatawins_registration_timeout().

参照元 multihomed_register_one()register_name()wins_next_registration()wins_refresh_name().

00245 {
00246         /*
00247          * If we are registering unicast, then NOT getting a response is an
00248          * error - we do not have the name. If we are registering broadcast,
00249          * then we don't expect to get a response.
00250          */
00251 
00252         struct nmb_packet *sent_nmb = &rrec->packet->packet.nmb;
00253         BOOL bcast = sent_nmb->header.nm_flags.bcast;
00254         BOOL success = False;
00255         struct nmb_name *question_name = &sent_nmb->question.question_name;
00256         uint16 nb_flags = 0;
00257         int ttl = 0;
00258         struct in_addr registered_ip;
00259         
00260         if (bcast) {
00261                 if(rrec->num_msgs == 0) {
00262                         /* Not receiving a message is success for broadcast registration. */
00263                         success = True; 
00264 
00265                         /* Pull the success values from the original request packet. */
00266                         nb_flags = get_nb_flags(sent_nmb->additional->rdata);
00267                         ttl = sent_nmb->additional->ttl;
00268                         putip(&registered_ip,&sent_nmb->additional->rdata[2]);
00269                 }
00270         } else {
00271                 /* wins timeouts are special */
00272                 wins_registration_timeout(subrec, rrec);
00273                 return;
00274         }
00275 
00276         DEBUG(5,("register_name_timeout_response: %s in registering name %s on subnet %s.\n",
00277                  success ? "success" : "failure", nmb_namestr(question_name), subrec->subnet_name));
00278         if(success) {
00279                 /* Enter the registered name into the subnet name database before calling
00280                    the success function. */
00281                 standard_success_register(subrec, rrec->userdata, question_name, nb_flags, ttl, registered_ip);
00282                 if( rrec->success_fn)
00283                         (*(register_name_success_function)rrec->success_fn)(subrec, rrec->userdata, question_name, nb_flags, ttl, registered_ip);
00284         } else {
00285                 struct nmb_name qname = *question_name;
00286                 if( rrec->fail_fn)
00287                         (*(register_name_fail_function)rrec->fail_fn)(subrec, rrec, question_name);
00288                 /* Remove the name. */
00289                 standard_fail_register( subrec, &qname);
00290         }
00291 
00292         /* Ensure we don't retry. */
00293         remove_response_record(subrec, rrec);
00294 }

static void multihomed_register_one ( struct nmb_name nmbname,
uint16  nb_flags,
register_name_success_function  success_fn,
register_name_fail_function  fail_fn,
struct in_addr  ip,
const char *  tag 
) [static]

nmbd_nameregister.c300 行で定義されています。

参照先 nmb_namestr()queue_register_multihomed_name()register_name_response()register_name_timeout_response()strlcpy()unicast_subnetwins_srv_ip_tag().

参照元 multihomed_register_name()wins_next_registration().

00306 {
00307         struct userdata_struct *userdata;
00308         struct in_addr wins_ip = wins_srv_ip_tag(tag, ip);
00309         fstring ip_str;
00310 
00311         userdata = (struct userdata_struct *)SMB_MALLOC(sizeof(*userdata) + strlen(tag) + 1);
00312         if (!userdata) {
00313                 DEBUG(0,("Failed to allocate userdata structure!\n"));
00314                 return;
00315         }
00316         ZERO_STRUCTP(userdata);
00317         userdata->userdata_len = strlen(tag) + 1;
00318         strlcpy(userdata->data, tag, userdata->userdata_len);   
00319 
00320         fstrcpy(ip_str, inet_ntoa(ip));
00321 
00322         DEBUG(6,("Registering name %s IP %s with WINS server %s using tag '%s'\n",
00323                  nmb_namestr(nmbname), ip_str, inet_ntoa(wins_ip), tag));
00324 
00325         if (queue_register_multihomed_name(unicast_subnet,
00326                                            register_name_response,
00327                                            register_name_timeout_response,
00328                                            success_fn,
00329                                            fail_fn,
00330                                            userdata,
00331                                            nmbname,
00332                                            nb_flags,
00333                                            ip,
00334                                            wins_ip) == NULL) {
00335                 DEBUG(0,("multihomed_register_one: Failed to send packet trying to register name %s IP %s\n", 
00336                          nmb_namestr(nmbname), inet_ntoa(ip)));         
00337         }
00338 
00339         free(userdata);
00340 }

static void multihomed_register_name ( struct nmb_name nmbname,
uint16  nb_flags,
register_name_success_function  success_fn,
register_name_fail_function  fail_fn 
) [static]

nmbd_nameregister.c395 行で定義されています。

参照先 add_name_to_subnet()multihomed_register_one()subnet_record::myipnmb_name::namenamenmb_name::name_typepull_ascii_nstring()SELF_NAMEtunicast_subnetwins_srv_tags()wins_srv_tags_free().

参照元 register_name().

00398 {
00399         /*
00400           If we are adding a group name, we just send multiple
00401           register name packets to the WINS server (this is an
00402           internet group name.
00403 
00404           If we are adding a unique name, We need first to add 
00405           our names to the unicast subnet namelist. This is 
00406           because when a WINS server receives a multihomed 
00407           registration request, the first thing it does is to 
00408           send a name query to the registering machine, to see 
00409           if it has put the name in it's local namelist.
00410           We need the name there so the query response code in
00411           nmbd_incomingrequests.c will find it.
00412 
00413           We are adding this name prematurely (we don't really
00414           have it yet), but as this is on the unicast subnet
00415           only we will get away with this (only the WINS server
00416           will ever query names from us on this subnet).
00417         */
00418         int num_ips=0;
00419         int i, t;
00420         struct subnet_record *subrec;
00421         char **wins_tags;
00422         struct in_addr *ip_list;
00423         unstring name;
00424 
00425         for(subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec) )
00426                 num_ips++;
00427         
00428         if((ip_list = SMB_MALLOC_ARRAY(struct in_addr, num_ips))==NULL) {
00429                 DEBUG(0,("multihomed_register_name: malloc fail !\n"));
00430                 return;
00431         }
00432 
00433         for (subrec = FIRST_SUBNET, i = 0; 
00434              subrec;
00435              subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec), i++ ) {
00436                 ip_list[i] = subrec->myip;
00437         }
00438 
00439         pull_ascii_nstring(name, sizeof(name), nmbname->name);
00440         add_name_to_subnet(unicast_subnet, name, nmbname->name_type,
00441                            nb_flags, lp_max_ttl(), SELF_NAME,
00442                            num_ips, ip_list);
00443 
00444         /* get the list of wins tags - we try to register for each of them */
00445         wins_tags = wins_srv_tags();
00446 
00447         /* Now try and register the name for each wins tag.  Note that
00448            at this point we only register our first IP with each wins
00449            group. We will register the rest from
00450            wins_next_registration() when we get the reply for this
00451            one. That follows the way W2K does things (tridge)
00452         */
00453         for (t=0; wins_tags && wins_tags[t]; t++) {
00454                 multihomed_register_one(nmbname, nb_flags,
00455                                         success_fn, fail_fn,
00456                                         ip_list[0],
00457                                         wins_tags[t]);
00458         }
00459 
00460         wins_srv_tags_free(wins_tags);
00461         
00462         SAFE_FREE(ip_list);
00463 }

void register_name ( struct subnet_record subrec,
const char *  name,
int  type,
uint16  nb_flags,
register_name_success_function  success_fn,
register_name_fail_function  fail_fn,
struct userdata_struct userdata 
)

nmbd_nameregister.c469 行で定義されています。

参照先 errnomake_nmb_name()multihomed_register_name()nmb_namestr()pull_ascii_nstring()push_ascii_nstring()queue_register_name()register_name_response()register_name_timeout_response()unicast_subnet.

参照元 become_domain_master_stage1()become_local_master_browser()become_local_master_stage1()become_logon_server()initiate_myworkgroup_startup()register_my_workgroup_one_subnet().

00474 {
00475         struct nmb_name nmbname;
00476         nstring nname;
00477 
00478         errno = 0;
00479         push_ascii_nstring(nname, name);
00480         if (errno == E2BIG) {
00481                 unstring tname;
00482                 pull_ascii_nstring(tname, sizeof(tname), nname);
00483                 DEBUG(0,("register_name: NetBIOS name %s is too long. Truncating to %s\n",
00484                         name, tname));
00485                 make_nmb_name(&nmbname, tname, type);
00486         } else {
00487                 make_nmb_name(&nmbname, name, type);
00488         }
00489 
00490         /* Always set the NB_ACTIVE flag on the name we are
00491            registering. Doesn't make sense without it.
00492         */
00493         
00494         nb_flags |= NB_ACTIVE;
00495         
00496         if (subrec == unicast_subnet) {
00497                 /* we now always do multi-homed registration if we are
00498                    registering to a WINS server. This copes much
00499                    better with complex WINS setups */
00500                 multihomed_register_name(&nmbname, nb_flags,
00501                                          success_fn, fail_fn);
00502                 return;
00503         }
00504         
00505         if (queue_register_name(subrec,
00506                                 register_name_response,
00507                                 register_name_timeout_response,
00508                                 success_fn,
00509                                 fail_fn,
00510                                 userdata,
00511                                 &nmbname,
00512                                 nb_flags) == NULL) {
00513                 DEBUG(0,("register_name: Failed to send packet trying to register name %s\n",
00514                          nmb_namestr(&nmbname)));
00515         }
00516 }

void wins_refresh_name ( struct name_record namerec  ) 

nmbd_nameregister.c522 行で定義されています。

参照先 name_record::datanmb_data::ipname_record::namenmb_data::nb_flagsqueue_wins_refresh()register_name_response()register_name_timeout_response()twins_srv_tags()wins_srv_tags_free().

参照元 refresh_my_names().

00523 {
00524         int t;
00525         char **wins_tags;
00526 
00527         /* get the list of wins tags - we try to refresh for each of them */
00528         wins_tags = wins_srv_tags();
00529 
00530         for (t=0; wins_tags && wins_tags[t]; t++) {
00531                 queue_wins_refresh(&namerec->name, 
00532                                    register_name_response,
00533                                    register_name_timeout_response,
00534                                    namerec->data.nb_flags,
00535                                    namerec->data.ip[0], wins_tags[t]);
00536         }
00537 
00538         wins_srv_tags_free(wins_tags);
00539 }


Sambaに対してSat Aug 29 21:23:53 2009に生成されました。  doxygen 1.4.7