関数 | |
static void | send_name_release_response (int rcode, struct packet_struct *p) |
void | process_name_release_request (struct subnet_record *subrec, struct packet_struct *p) |
static void | send_name_registration_response (int rcode, int ttl, struct packet_struct *p) |
void | process_name_refresh_request (struct subnet_record *subrec, struct packet_struct *p) |
void | process_name_registration_request (struct subnet_record *subrec, struct packet_struct *p) |
static int | status_compare (char *n1, char *n2) |
void | process_node_status_request (struct subnet_record *subrec, struct packet_struct *p) |
void | process_name_query_request (struct subnet_record *subrec, struct packet_struct *p) |
static void send_name_release_response | ( | int | rcode, | |
struct packet_struct * | p | |||
) | [static] |
nmbd_incomingrequests.c の 34 行で定義されています。
参照先 nmb_packet::additional・packet_struct::nmb・NMB_REL・packet_struct::packet・res_rec::rdata・reply_netbios_packet().
参照元 process_name_release_request().
00035 { 00036 struct nmb_packet *nmb = &p->packet.nmb; 00037 char rdata[6]; 00038 00039 memcpy(&rdata[0], &nmb->additional->rdata[0], 6); 00040 00041 reply_netbios_packet(p, /* Packet to reply to. */ 00042 rcode, /* Result code. */ 00043 NMB_REL, /* nmbd type code. */ 00044 NMB_NAME_RELEASE_OPCODE, /* opcode. */ 00045 0, /* ttl. */ 00046 rdata, /* data to send. */ 00047 6); /* data length. */ 00048 }
void process_name_release_request | ( | struct subnet_record * | subrec, | |
struct packet_struct * | p | |||
) |
nmbd_incomingrequests.c の 55 行で定義されています。
参照先 nmb_packet::additional・name_record::data・find_name_on_subnet()・get_nb_flags()・nmb_packet::header・ismyip()・lp_workgroup()・nmb_name::name・nmb_name::name_type・nmb_packet::nm_flags・packet_struct::nmb・nmb_namestr()・packet_struct::packet・PERMANENT_NAME・pull_ascii_nstring()・nmb_packet::question・nmb_packet::question_name・res_rec::rdata・SELF_NAME・send_name_release_response()・nmb_data::source・strequal()・subnet_record::subnet_name.
00057 { 00058 struct nmb_packet *nmb = &p->packet.nmb; 00059 struct in_addr owner_ip; 00060 struct nmb_name *question = &nmb->question.question_name; 00061 unstring qname; 00062 BOOL bcast = nmb->header.nm_flags.bcast; 00063 uint16 nb_flags = get_nb_flags(nmb->additional->rdata); 00064 BOOL group = (nb_flags & NB_GROUP) ? True : False; 00065 struct name_record *namerec; 00066 int rcode = 0; 00067 00068 putip((char *)&owner_ip,&nmb->additional->rdata[2]); 00069 00070 if(!bcast) { 00071 /* We should only get broadcast name release packets here. 00072 Anyone trying to release unicast should be going to a WINS 00073 server. If the code gets here, then either we are not a wins 00074 server and they sent it anyway, or we are a WINS server and 00075 the request was malformed. Either way, log an error here. 00076 and send an error reply back. 00077 */ 00078 DEBUG(0,("process_name_release_request: unicast name release request \ 00079 received for name %s from IP %s on subnet %s. Error - should be sent to WINS server\n", 00080 nmb_namestr(question), inet_ntoa(owner_ip), subrec->subnet_name)); 00081 00082 send_name_release_response(FMT_ERR, p); 00083 return; 00084 } 00085 00086 DEBUG(3,("process_name_release_request: Name release on name %s, \ 00087 subnet %s from owner IP %s\n", 00088 nmb_namestr(&nmb->question.question_name), 00089 subrec->subnet_name, inet_ntoa(owner_ip))); 00090 00091 /* If someone is releasing a broadcast group name, just ignore it. */ 00092 if( group && !ismyip(owner_ip) ) 00093 return; 00094 00095 /* 00096 * Code to work around a bug in FTP OnNet software NBT implementation. 00097 * They do a broadcast name release for WORKGROUP<0> and WORKGROUP<1e> 00098 * names and *don't set the group bit* !!!!! 00099 */ 00100 00101 pull_ascii_nstring(qname, sizeof(qname), question->name); 00102 if( !group && !ismyip(owner_ip) && strequal(qname, lp_workgroup()) && 00103 ((question->name_type == 0x0) || (question->name_type == 0x1e))) { 00104 DEBUG(6,("process_name_release_request: FTP OnNet bug workaround. Ignoring \ 00105 group release name %s from IP %s on subnet %s with no group bit set.\n", 00106 nmb_namestr(question), inet_ntoa(owner_ip), subrec->subnet_name )); 00107 return; 00108 } 00109 00110 namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME); 00111 00112 /* We only care about someone trying to release one of our names. */ 00113 if( namerec && ( (namerec->data.source == SELF_NAME) 00114 || (namerec->data.source == PERMANENT_NAME) ) ) { 00115 rcode = ACT_ERR; 00116 DEBUG(0, ("process_name_release_request: Attempt to release name %s from IP %s \ 00117 on subnet %s being rejected as it is one of our names.\n", 00118 nmb_namestr(&nmb->question.question_name), inet_ntoa(owner_ip), subrec->subnet_name)); 00119 } 00120 00121 if(rcode == 0) 00122 return; 00123 00124 /* Send a NAME RELEASE RESPONSE (pos/neg) see rfc1002.txt 4.2.10-11 */ 00125 send_name_release_response(rcode, p); 00126 }
static void send_name_registration_response | ( | int | rcode, | |
int | ttl, | |||
struct packet_struct * | p | |||
) | [static] |
nmbd_incomingrequests.c の 132 行で定義されています。
参照先 nmb_packet::additional・packet_struct::nmb・NMB_REG・packet_struct::packet・res_rec::rdata・reply_netbios_packet().
参照元 process_name_refresh_request()・process_name_registration_request().
00133 { 00134 struct nmb_packet *nmb = &p->packet.nmb; 00135 char rdata[6]; 00136 00137 memcpy(&rdata[0], &nmb->additional->rdata[0], 6); 00138 00139 reply_netbios_packet(p, /* Packet to reply to. */ 00140 rcode, /* Result code. */ 00141 NMB_REG, /* nmbd type code. */ 00142 NMB_NAME_REG_OPCODE, /* opcode. */ 00143 ttl, /* ttl. */ 00144 rdata, /* data to send. */ 00145 6); /* data length. */ 00146 }
void process_name_refresh_request | ( | struct subnet_record * | subrec, | |
struct packet_struct * | p | |||
) |
nmbd_incomingrequests.c の 152 行で定義されています。
参照先 nmb_packet::additional・nmb_packet::header・nmb_packet::nm_flags・packet_struct::nmb・nmb_namestr()・packet_struct::packet・nmb_packet::question・nmb_packet::question_name・res_rec::rdata・send_name_registration_response()・subnet_record::subnet_name.
00154 { 00155 struct nmb_packet *nmb = &p->packet.nmb; 00156 struct nmb_name *question = &nmb->question.question_name; 00157 BOOL bcast = nmb->header.nm_flags.bcast; 00158 struct in_addr from_ip; 00159 00160 putip((char *)&from_ip,&nmb->additional->rdata[2]); 00161 00162 if(!bcast) { 00163 /* We should only get broadcast name refresh packets here. 00164 Anyone trying to refresh unicast should be going to a WINS 00165 server. If the code gets here, then either we are not a wins 00166 server and they sent it anyway, or we are a WINS server and 00167 the request was malformed. Either way, log an error here. 00168 and send an error reply back. 00169 */ 00170 DEBUG(0,("process_name_refresh_request: unicast name registration request \ 00171 received for name %s from IP %s on subnet %s.\n", 00172 nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name)); 00173 DEBUG(0,("Error - should be sent to WINS server\n")); 00174 00175 send_name_registration_response(FMT_ERR, 0, p); 00176 return; 00177 } 00178 00179 /* Just log a message. We really don't care about broadcast name refreshes. */ 00180 00181 DEBUG(3,("process_name_refresh_request: Name refresh for name %s \ 00182 IP %s on subnet %s\n", nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name)); 00183 }
void process_name_registration_request | ( | struct subnet_record * | subrec, | |
struct packet_struct * | p | |||
) |
nmbd_incomingrequests.c の 189 行で定義されています。
参照先 nmb_packet::additional・name_record::data・find_name_on_subnet()・get_nb_flags()・nmb_packet::header・nmb_data::ip・name_record::name・nmb_packet::nm_flags・packet_struct::nmb・nmb_namestr()・packet_struct::packet・PERMANENT_NAME・nmb_packet::question・nmb_packet::question_name・res_rec::rdata・remove_name_from_namelist()・SELF_NAME・send_name_registration_response()・nmb_data::source・subnet_record::subnet_name・res_rec::ttl・update_name_ttl()・WINS_PROXY_NAME.
00191 { 00192 struct nmb_packet *nmb = &p->packet.nmb; 00193 struct nmb_name *question = &nmb->question.question_name; 00194 BOOL bcast = nmb->header.nm_flags.bcast; 00195 uint16 nb_flags = get_nb_flags(nmb->additional->rdata); 00196 BOOL group = (nb_flags & NB_GROUP) ? True : False; 00197 struct name_record *namerec = NULL; 00198 int ttl = nmb->additional->ttl; 00199 struct in_addr from_ip; 00200 00201 putip((char *)&from_ip,&nmb->additional->rdata[2]); 00202 00203 if(!bcast) { 00204 /* We should only get broadcast name registration packets here. 00205 Anyone trying to register unicast should be going to a WINS 00206 server. If the code gets here, then either we are not a wins 00207 server and they sent it anyway, or we are a WINS server and 00208 the request was malformed. Either way, log an error here. 00209 and send an error reply back. 00210 */ 00211 DEBUG(0,("process_name_registration_request: unicast name registration request \ 00212 received for name %s from IP %s on subnet %s. Error - should be sent to WINS server\n", 00213 nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name)); 00214 00215 send_name_registration_response(FMT_ERR, 0, p); 00216 return; 00217 } 00218 00219 DEBUG(3,("process_name_registration_request: Name registration for name %s \ 00220 IP %s on subnet %s\n", nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name)); 00221 00222 /* See if the name already exists. */ 00223 namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME); 00224 00225 /* 00226 * If the name being registered exists and is a WINS_PROXY_NAME 00227 * then delete the WINS proxy name entry so we don't reply erroneously 00228 * later to queries. 00229 */ 00230 00231 if((namerec != NULL) && (namerec->data.source == WINS_PROXY_NAME)) { 00232 remove_name_from_namelist( subrec, namerec ); 00233 namerec = NULL; 00234 } 00235 00236 if (!group) { 00237 /* Unique name. */ 00238 00239 if( (namerec != NULL) 00240 && ( (namerec->data.source == SELF_NAME) 00241 || (namerec->data.source == PERMANENT_NAME) 00242 || NAME_GROUP(namerec) ) ) { 00243 /* No-one can register one of Samba's names, nor can they 00244 register a name that's a group name as a unique name */ 00245 00246 send_name_registration_response(ACT_ERR, 0, p); 00247 return; 00248 } else if(namerec != NULL) { 00249 /* Update the namelist record with the new information. */ 00250 namerec->data.ip[0] = from_ip; 00251 update_name_ttl(namerec, ttl); 00252 00253 DEBUG(3,("process_name_registration_request: Updated name record %s \ 00254 with IP %s on subnet %s\n",nmb_namestr(&namerec->name),inet_ntoa(from_ip), subrec->subnet_name)); 00255 return; 00256 } 00257 } else { 00258 /* Group name. */ 00259 00260 if( (namerec != NULL) 00261 && !NAME_GROUP(namerec) 00262 && ( (namerec->data.source == SELF_NAME) 00263 || (namerec->data.source == PERMANENT_NAME) ) ) { 00264 /* Disallow group names when we have a unique name. */ 00265 send_name_registration_response(ACT_ERR, 0, p); 00266 return; 00267 } 00268 } 00269 }
static int status_compare | ( | char * | n1, | |
char * | n2 | |||
) | [static] |
nmbd_incomingrequests.c の 276 行で定義されています。
参照先 global_myname・pull_ascii_nstring().
参照元 process_node_status_request().
00277 { 00278 unstring name1, name2; 00279 int l1,l2,l3; 00280 00281 memset(name1, '\0', sizeof(name1)); 00282 memset(name2, '\0', sizeof(name2)); 00283 pull_ascii_nstring(name1, sizeof(name1), n1); 00284 pull_ascii_nstring(name2, sizeof(name2), n2); 00285 n1 = name1; 00286 n2 = name2; 00287 00288 /* It's a bit tricky because the names are space padded */ 00289 for (l1=0;l1<15 && n1[l1] && n1[l1] != ' ';l1++) 00290 ; 00291 for (l2=0;l2<15 && n2[l2] && n2[l2] != ' ';l2++) 00292 ; 00293 l3 = strlen(global_myname()); 00294 00295 if ((l1==l3) && strncmp(n1,global_myname(),l3) == 0 && 00296 (l2!=l3 || strncmp(n2,global_myname(),l3) != 0)) 00297 return -1; 00298 00299 if ((l2==l3) && strncmp(n2,global_myname(),l3) == 0 && 00300 (l1!=l3 || strncmp(n1,global_myname(),l3) != 0)) 00301 return 1; 00302 00303 return memcmp(n1,n2,sizeof(name1)); 00304 }
void process_node_status_request | ( | struct subnet_record * | subrec, | |
struct packet_struct * | p | |||
) |
nmbd_incomingrequests.c の 310 行で定義されています。
参照先 buf・name_record::data・find_name_on_subnet()・packet_struct::ip・len・name・name_record::name・nmb_name::name・name_type・nmb_name::name_type・subnet_record::namelist・nmb_data::nb_flags・name_record::next・packet_struct::nmb・nmb_namestr()・NMB_STATUS・packet_struct::packet・PERMANENT_NAME・pull_ascii_nstring()・push_ascii_nstring()・nmb_packet::question・nmb_packet::question_name・reply_netbios_packet()・SELF_NAME・set_nb_flags()・nmb_data::source・status_compare()・strequal()・strupper_m()・subnet_record::subnet_name・unicast_subnet.
00311 { 00312 struct nmb_packet *nmb = &p->packet.nmb; 00313 unstring qname; 00314 int ques_type = nmb->question.question_name.name_type; 00315 char rdata[MAX_DGRAM_SIZE]; 00316 char *countptr, *buf, *bufend, *buf0; 00317 int names_added,i; 00318 struct name_record *namerec; 00319 00320 pull_ascii_nstring(qname, sizeof(qname), nmb->question.question_name.name); 00321 00322 DEBUG(3,("process_node_status_request: status request for name %s from IP %s on \ 00323 subnet %s.\n", nmb_namestr(&nmb->question.question_name), inet_ntoa(p->ip), subrec->subnet_name)); 00324 00325 if((namerec = find_name_on_subnet(subrec, &nmb->question.question_name, FIND_SELF_NAME)) == 0) { 00326 DEBUG(1,("process_node_status_request: status request for name %s from IP %s on \ 00327 subnet %s - name not found.\n", nmb_namestr(&nmb->question.question_name), 00328 inet_ntoa(p->ip), subrec->subnet_name)); 00329 00330 return; 00331 } 00332 00333 /* this is not an exact calculation. the 46 is for the stats buffer 00334 and the 60 is to leave room for the header etc */ 00335 bufend = &rdata[MAX_DGRAM_SIZE] - (18 + 46 + 60); 00336 countptr = buf = rdata; 00337 buf += 1; 00338 buf0 = buf; 00339 00340 names_added = 0; 00341 00342 namerec = subrec->namelist; 00343 00344 while (buf < bufend) { 00345 if( (namerec->data.source == SELF_NAME) || (namerec->data.source == PERMANENT_NAME) ) { 00346 int name_type = namerec->name.name_type; 00347 unstring name; 00348 00349 pull_ascii_nstring(name, sizeof(name), namerec->name.name); 00350 strupper_m(name); 00351 if (!strequal(name,"*") && 00352 !strequal(name,"__SAMBA__") && 00353 (name_type < 0x1b || name_type >= 0x20 || 00354 ques_type < 0x1b || ques_type >= 0x20 || 00355 strequal(qname, name))) { 00356 /* Start with the name. */ 00357 size_t len; 00358 push_ascii_nstring(buf, name); 00359 len = strlen(buf); 00360 memset(buf + len, ' ', MAX_NETBIOSNAME_LEN - len - 1); 00361 buf[MAX_NETBIOSNAME_LEN - 1] = '\0'; 00362 00363 /* Put the name type and netbios flags in the buffer. */ 00364 00365 buf[15] = name_type; 00366 set_nb_flags( &buf[16],namerec->data.nb_flags ); 00367 buf[16] |= NB_ACTIVE; /* all our names are active */ 00368 00369 buf += 18; 00370 00371 names_added++; 00372 } 00373 } 00374 00375 /* Remove duplicate names. */ 00376 if (names_added > 1) { 00377 qsort( buf0, names_added, 18, QSORT_CAST status_compare ); 00378 } 00379 00380 for( i=1; i < names_added ; i++ ) { 00381 if (memcmp(buf0 + 18*i,buf0 + 18*(i-1),16) == 0) { 00382 names_added--; 00383 if (names_added == i) 00384 break; 00385 memmove(buf0 + 18*i,buf0 + 18*(i+1),18*(names_added-i)); 00386 i--; 00387 } 00388 } 00389 00390 buf = buf0 + 18*names_added; 00391 00392 namerec = namerec->next; 00393 00394 if (!namerec) { 00395 /* End of the subnet specific name list. Now 00396 add the names on the unicast subnet . */ 00397 struct subnet_record *uni_subrec = unicast_subnet; 00398 00399 if (uni_subrec != subrec) { 00400 subrec = uni_subrec; 00401 namerec = subrec->namelist; 00402 } 00403 } 00404 if (!namerec) 00405 break; 00406 00407 } 00408 00409 SCVAL(countptr,0,names_added); 00410 00411 /* We don't send any stats as they could be used to attack 00412 the protocol. */ 00413 memset(buf,'\0',46); 00414 00415 buf += 46; 00416 00417 /* Send a NODE STATUS RESPONSE */ 00418 reply_netbios_packet(p, /* Packet to reply to. */ 00419 0, /* Result code. */ 00420 NMB_STATUS, /* nmbd type code. */ 00421 NMB_NAME_QUERY_OPCODE, /* opcode. */ 00422 0, /* ttl. */ 00423 rdata, /* data to send. */ 00424 PTR_DIFF(buf,rdata)); /* data length. */ 00425 }
void process_name_query_request | ( | struct subnet_record * | subrec, | |
struct packet_struct * | p | |||
) |
nmbd_incomingrequests.c の 438 行で定義されています。
参照先 name_record::data・nmb_data::death_time・find_name_for_remote_broadcast_subnet()・find_name_on_subnet()・nmb_packet::header・nmb_data::ip・packet_struct::ip・subnet_record::mask_ip・subnet_record::myip・name_record::name・nmb_name::name_type・name_type・nmb_packet::nm_flags・packet_struct::nmb・nmb_namestr()・nmb_data::num_ips・packet_struct::packet・PERMANENT_NAME・nmb_packet::question・nmb_packet::question_name・remote_broadcast_subnet・same_net()・SELF_NAME・nmb_data::source・subnet_record::subnet_name・packet_struct::timestamp・WINS_PROXY_NAME.
00439 { 00440 struct nmb_packet *nmb = &p->packet.nmb; 00441 struct nmb_name *question = &nmb->question.question_name; 00442 int name_type = question->name_type; 00443 BOOL bcast = nmb->header.nm_flags.bcast; 00444 int ttl=0; 00445 int rcode = 0; 00446 char *prdata = NULL; 00447 char rdata[6]; 00448 BOOL success = False; 00449 struct name_record *namerec = NULL; 00450 int reply_data_len = 0; 00451 int i; 00452 00453 DEBUG(3,("process_name_query_request: Name query from %s on subnet %s for name %s\n", 00454 inet_ntoa(p->ip), subrec->subnet_name, nmb_namestr(question))); 00455 00456 /* Look up the name in the cache - if the request is a broadcast request that 00457 came from a subnet we don't know about then search all the broadcast subnets 00458 for a match (as we don't know what interface the request came in on). */ 00459 00460 if(subrec == remote_broadcast_subnet) 00461 namerec = find_name_for_remote_broadcast_subnet( question, FIND_ANY_NAME); 00462 else 00463 namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME); 00464 00465 /* Check if it is a name that expired */ 00466 if (namerec && 00467 ((namerec->data.death_time != PERMANENT_TTL) && 00468 (namerec->data.death_time < p->timestamp))) { 00469 DEBUG(5,("process_name_query_request: expired name %s\n", nmb_namestr(&namerec->name))); 00470 namerec = NULL; 00471 } 00472 00473 if (namerec) { 00474 /* 00475 * Always respond to unicast queries. 00476 * Don't respond to broadcast queries unless the query is for 00477 * a name we own, a Primary Domain Controller name, or a WINS_PROXY 00478 * name with type 0 or 0x20. WINS_PROXY names are only ever added 00479 * into the namelist if we were configured as a WINS proxy. 00480 */ 00481 00482 if (!bcast || 00483 (bcast && ((name_type == 0x1b) || 00484 (namerec->data.source == SELF_NAME) || 00485 (namerec->data.source == PERMANENT_NAME) || 00486 ((namerec->data.source == WINS_PROXY_NAME) && 00487 ((name_type == 0) || (name_type == 0x20)))))) { 00488 /* The requested name is a directed query, or it's SELF or PERMANENT or WINS_PROXY, 00489 or it's a Domain Master type. */ 00490 00491 /* 00492 * If this is a WINS_PROXY_NAME, then ceck that none of the IP 00493 * addresses we are returning is on the same broadcast subnet 00494 * as the requesting packet. If it is then don't reply as the 00495 * actual machine will be replying also and we don't want two 00496 * replies to a broadcast query. 00497 */ 00498 00499 if (namerec->data.source == WINS_PROXY_NAME) { 00500 for( i = 0; i < namerec->data.num_ips; i++) { 00501 if (same_net(namerec->data.ip[i], subrec->myip, subrec->mask_ip)) { 00502 DEBUG(5,("process_name_query_request: name %s is a WINS proxy name and is also on the same subnet (%s) as the requestor. Not replying.\n", 00503 nmb_namestr(&namerec->name), subrec->subnet_name )); 00504 return; 00505 } 00506 } 00507 } 00508 00509 ttl = (namerec->data.death_time != PERMANENT_TTL) ? 00510 namerec->data.death_time - p->timestamp : lp_max_ttl(); 00511 00512 /* Copy all known ip addresses into the return data. */ 00513 /* Optimise for the common case of one IP address so 00514 we don't need a malloc. */ 00515 00516 if (namerec->data.num_ips == 1) { 00517 prdata = rdata; 00518 } else { 00519 if ((prdata = (char *)SMB_MALLOC( namerec->data.num_ips * 6 )) == NULL) { 00520 DEBUG(0,("process_name_query_request: malloc fail !\n")); 00521 return; 00522 } 00523 } 00524 00525 for (i = 0; i < namerec->data.num_ips; i++) { 00526 set_nb_flags(&prdata[i*6],namerec->data.nb_flags); 00527 putip((char *)&prdata[2+(i*6)], &namerec->data.ip[i]); 00528 } 00529 00530 sort_query_replies(prdata, i, p->ip); 00531 00532 reply_data_len = namerec->data.num_ips * 6; 00533 success = True; 00534 } 00535 } 00536 00537 /* 00538 * If a machine is broadcasting a name lookup request and we have lp_wins_proxy() 00539 * set we should initiate a WINS query here. On success we add the resolved name 00540 * into our namelist with a type of WINS_PROXY_NAME and then reply to the query. 00541 */ 00542 00543 if(!success && (namerec == NULL) && we_are_a_wins_client() && lp_wins_proxy() && 00544 bcast && (subrec != remote_broadcast_subnet)) { 00545 make_wins_proxy_name_query_request( subrec, p, question ); 00546 return; 00547 } 00548 00549 if (!success && bcast) { 00550 if(prdata != rdata) 00551 SAFE_FREE(prdata); 00552 return; /* Never reply with a negative response to broadcasts. */ 00553 } 00554 00555 /* 00556 * Final check. From observation, if a unicast packet is sent 00557 * to a non-WINS server with the recursion desired bit set 00558 * then never send a negative response. 00559 */ 00560 00561 if(!success && !bcast && nmb->header.nm_flags.recursion_desired) { 00562 if(prdata != rdata) 00563 SAFE_FREE(prdata); 00564 return; 00565 } 00566 00567 if (success) { 00568 rcode = 0; 00569 DEBUG(3,("OK\n")); 00570 } else { 00571 rcode = NAM_ERR; 00572 DEBUG(3,("UNKNOWN\n")); 00573 } 00574 00575 /* See rfc1002.txt 4.2.13. */ 00576 00577 reply_netbios_packet(p, /* Packet to reply to. */ 00578 rcode, /* Result code. */ 00579 NMB_QUERY, /* nmbd type code. */ 00580 NMB_NAME_QUERY_OPCODE, /* opcode. */ 00581 ttl, /* ttl. */ 00582 prdata, /* data to send. */ 00583 reply_data_len); /* data length. */ 00584 00585 if(prdata != rdata) 00586 SAFE_FREE(prdata); 00587 }