00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "includes.h"
00025
00026 extern int ClientNMB;
00027 extern int ClientDGRAM;
00028 extern int global_nmb_port;
00029
00030 extern int num_response_packets;
00031
00032 extern struct in_addr loopback_ip;
00033
00034 static void queue_packet(struct packet_struct *packet);
00035
00036 BOOL rescan_listen_set = False;
00037
00038
00039
00040
00041
00042
00043
00044
00045 static struct packet_struct *packet_queue = NULL;
00046
00047
00048
00049
00050
00051 static int find_subnet_fd_for_address( struct in_addr local_ip )
00052 {
00053 struct subnet_record *subrec;
00054
00055 for( subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
00056 if(ip_equal(local_ip, subrec->myip))
00057 return subrec->nmb_sock;
00058
00059 return ClientNMB;
00060 }
00061
00062
00063
00064
00065
00066 static int find_subnet_mailslot_fd_for_address( struct in_addr local_ip )
00067 {
00068 struct subnet_record *subrec;
00069
00070 for( subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
00071 if(ip_equal(local_ip, subrec->myip))
00072 return subrec->dgram_sock;
00073
00074 return ClientDGRAM;
00075 }
00076
00077
00078
00079
00080
00081 uint16 get_nb_flags(char *buf)
00082 {
00083 return ((((uint16)*buf)&0xFFFF) & NB_FLGMSK);
00084 }
00085
00086 void set_nb_flags(char *buf, uint16 nb_flags)
00087 {
00088 *buf++ = ((nb_flags & NB_FLGMSK) & 0xFF);
00089 *buf = '\0';
00090 }
00091
00092
00093
00094
00095
00096 static void debug_browse_data(char *outbuf, int len)
00097 {
00098 int i,j;
00099
00100 DEBUG( 4, ( "debug_browse_data():\n" ) );
00101 for (i = 0; i < len; i+= 16) {
00102 DEBUGADD( 4, ( "%3x char ", i ) );
00103
00104 for (j = 0; j < 16; j++) {
00105 unsigned char x;
00106 if (i+j >= len)
00107 break;
00108
00109 x = outbuf[i+j];
00110 if (x < 32 || x > 127)
00111 x = '.';
00112
00113 DEBUGADD( 4, ( "%c", x ) );
00114 }
00115
00116 DEBUGADD( 4, ( "%*s hex", 16-j, "" ) );
00117
00118 for (j = 0; j < 16; j++) {
00119 if (i+j >= len)
00120 break;
00121 DEBUGADD( 4, ( " %02x", (unsigned char)outbuf[i+j] ) );
00122 }
00123
00124 DEBUGADD( 4, ("\n") );
00125 }
00126 }
00127
00128
00129
00130
00131
00132 static uint16 name_trn_id=0;
00133
00134 static uint16 generate_name_trn_id(void)
00135 {
00136 if (!name_trn_id) {
00137 name_trn_id = ((unsigned)time(NULL)%(unsigned)0x7FFF) + ((unsigned)sys_getpid()%(unsigned)100);
00138 }
00139 name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
00140 return name_trn_id;
00141 }
00142
00143
00144
00145
00146
00147 static BOOL send_netbios_packet(struct packet_struct *p)
00148 {
00149 BOOL loopback_this_packet = False;
00150
00151
00152 if(ismyip(p->ip) && (p->port == global_nmb_port))
00153 loopback_this_packet = True;
00154
00155 if(loopback_this_packet) {
00156 struct packet_struct *lo_packet = NULL;
00157 DEBUG(5,("send_netbios_packet: sending packet to ourselves.\n"));
00158 if((lo_packet = copy_packet(p)) == NULL)
00159 return False;
00160 queue_packet(lo_packet);
00161 } else if (!send_packet(p)) {
00162 DEBUG(0,("send_netbios_packet: send_packet() to IP %s port %d failed\n",
00163 inet_ntoa(p->ip),p->port));
00164 return False;
00165 }
00166
00167 return True;
00168 }
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179 static struct packet_struct *create_and_init_netbios_packet(struct nmb_name *nmbname,
00180 BOOL bcast, BOOL rec_des,
00181 struct in_addr to_ip)
00182 {
00183 struct packet_struct *packet = NULL;
00184 struct nmb_packet *nmb = NULL;
00185
00186
00187 if((packet = SMB_MALLOC_P(struct packet_struct)) == NULL) {
00188 DEBUG(0,("create_and_init_netbios_packet: malloc fail (1) for packet struct.\n"));
00189 return NULL;
00190 }
00191
00192 memset((char *)packet,'\0',sizeof(*packet));
00193
00194 nmb = &packet->packet.nmb;
00195
00196 nmb->header.name_trn_id = generate_name_trn_id();
00197 nmb->header.response = False;
00198 nmb->header.nm_flags.recursion_desired = rec_des;
00199 nmb->header.nm_flags.recursion_available = False;
00200 nmb->header.nm_flags.trunc = False;
00201 nmb->header.nm_flags.authoritative = False;
00202 nmb->header.nm_flags.bcast = bcast;
00203
00204 nmb->header.rcode = 0;
00205 nmb->header.qdcount = 1;
00206 nmb->header.ancount = 0;
00207 nmb->header.nscount = 0;
00208
00209 nmb->question.question_name = *nmbname;
00210 nmb->question.question_type = QUESTION_TYPE_NB_QUERY;
00211 nmb->question.question_class = QUESTION_CLASS_IN;
00212
00213 packet->ip = to_ip;
00214 packet->port = NMB_PORT;
00215 packet->fd = ClientNMB;
00216 packet->timestamp = time(NULL);
00217 packet->packet_type = NMB_PACKET;
00218 packet->locked = False;
00219
00220 return packet;
00221 }
00222
00223
00224
00225
00226
00227 static BOOL create_and_init_additional_record(struct packet_struct *packet,
00228 uint16 nb_flags,
00229 struct in_addr *register_ip)
00230 {
00231 struct nmb_packet *nmb = &packet->packet.nmb;
00232
00233 if((nmb->additional = SMB_MALLOC_P(struct res_rec)) == NULL) {
00234 DEBUG(0,("initiate_name_register_packet: malloc fail for additional record.\n"));
00235 return False;
00236 }
00237
00238 memset((char *)nmb->additional,'\0',sizeof(struct res_rec));
00239
00240 nmb->additional->rr_name = nmb->question.question_name;
00241 nmb->additional->rr_type = RR_TYPE_NB;
00242 nmb->additional->rr_class = RR_CLASS_IN;
00243
00244
00245 if (nmb->header.nm_flags.bcast)
00246 nmb->additional->ttl = PERMANENT_TTL;
00247 else
00248 nmb->additional->ttl = lp_max_ttl();
00249
00250 nmb->additional->rdlength = 6;
00251
00252 set_nb_flags(nmb->additional->rdata,nb_flags);
00253
00254
00255 putip(&nmb->additional->rdata[2], register_ip);
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266 packet->fd = find_subnet_fd_for_address(*register_ip);
00267
00268 return True;
00269 }
00270
00271
00272
00273
00274
00275 static BOOL initiate_name_query_packet( struct packet_struct *packet)
00276 {
00277 struct nmb_packet *nmb = NULL;
00278
00279 nmb = &packet->packet.nmb;
00280
00281 nmb->header.opcode = NMB_NAME_QUERY_OPCODE;
00282 nmb->header.arcount = 0;
00283
00284 nmb->header.nm_flags.recursion_desired = True;
00285
00286 DEBUG(4,("initiate_name_query_packet: sending query for name %s (bcast=%s) to IP %s\n",
00287 nmb_namestr(&nmb->question.question_name),
00288 BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
00289
00290 return send_netbios_packet( packet );
00291 }
00292
00293
00294
00295
00296
00297 static BOOL initiate_name_query_packet_from_wins_server( struct packet_struct *packet)
00298 {
00299 struct nmb_packet *nmb = NULL;
00300
00301 nmb = &packet->packet.nmb;
00302
00303 nmb->header.opcode = NMB_NAME_QUERY_OPCODE;
00304 nmb->header.arcount = 0;
00305
00306 nmb->header.nm_flags.recursion_desired = False;
00307
00308 DEBUG(4,("initiate_name_query_packet_from_wins_server: sending query for name %s (bcast=%s) to IP %s\n",
00309 nmb_namestr(&nmb->question.question_name),
00310 BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
00311
00312 return send_netbios_packet( packet );
00313 }
00314
00315
00316
00317
00318
00319 static BOOL initiate_name_register_packet( struct packet_struct *packet,
00320 uint16 nb_flags, struct in_addr *register_ip)
00321 {
00322 struct nmb_packet *nmb = &packet->packet.nmb;
00323
00324 nmb->header.opcode = NMB_NAME_REG_OPCODE;
00325 nmb->header.arcount = 1;
00326
00327 nmb->header.nm_flags.recursion_desired = True;
00328
00329 if(create_and_init_additional_record(packet, nb_flags, register_ip) == False)
00330 return False;
00331
00332 DEBUG(4,("initiate_name_register_packet: sending registration for name %s (bcast=%s) to IP %s\n",
00333 nmb_namestr(&nmb->additional->rr_name),
00334 BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
00335
00336 return send_netbios_packet( packet );
00337 }
00338
00339
00340
00341
00342
00343 static BOOL initiate_multihomed_name_register_packet(struct packet_struct *packet,
00344 uint16 nb_flags, struct in_addr *register_ip)
00345 {
00346 struct nmb_packet *nmb = &packet->packet.nmb;
00347 fstring second_ip_buf;
00348
00349 fstrcpy(second_ip_buf, inet_ntoa(packet->ip));
00350
00351 nmb->header.opcode = NMB_NAME_MULTIHOMED_REG_OPCODE;
00352 nmb->header.arcount = 1;
00353
00354 nmb->header.nm_flags.recursion_desired = True;
00355
00356 if(create_and_init_additional_record(packet, nb_flags, register_ip) == False)
00357 return False;
00358
00359 DEBUG(4,("initiate_multihomed_name_register_packet: sending registration \
00360 for name %s IP %s (bcast=%s) to IP %s\n",
00361 nmb_namestr(&nmb->additional->rr_name), inet_ntoa(*register_ip),
00362 BOOLSTR(nmb->header.nm_flags.bcast), second_ip_buf ));
00363
00364 return send_netbios_packet( packet );
00365 }
00366
00367
00368
00369
00370
00371 static BOOL initiate_name_refresh_packet( struct packet_struct *packet,
00372 uint16 nb_flags, struct in_addr *refresh_ip)
00373 {
00374 struct nmb_packet *nmb = &packet->packet.nmb;
00375
00376 nmb->header.opcode = NMB_NAME_REFRESH_OPCODE_8;
00377 nmb->header.arcount = 1;
00378
00379 nmb->header.nm_flags.recursion_desired = False;
00380
00381 if(create_and_init_additional_record(packet, nb_flags, refresh_ip) == False)
00382 return False;
00383
00384 DEBUG(4,("initiate_name_refresh_packet: sending refresh for name %s (bcast=%s) to IP %s\n",
00385 nmb_namestr(&nmb->additional->rr_name),
00386 BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
00387
00388 return send_netbios_packet( packet );
00389 }
00390
00391
00392
00393
00394
00395 static BOOL initiate_name_release_packet( struct packet_struct *packet,
00396 uint16 nb_flags, struct in_addr *release_ip)
00397 {
00398 struct nmb_packet *nmb = &packet->packet.nmb;
00399
00400 nmb->header.opcode = NMB_NAME_RELEASE_OPCODE;
00401 nmb->header.arcount = 1;
00402
00403 nmb->header.nm_flags.recursion_desired = False;
00404
00405 if(create_and_init_additional_record(packet, nb_flags, release_ip) == False)
00406 return False;
00407
00408 DEBUG(4,("initiate_name_release_packet: sending release for name %s (bcast=%s) to IP %s\n",
00409 nmb_namestr(&nmb->additional->rr_name),
00410 BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
00411
00412 return send_netbios_packet( packet );
00413 }
00414
00415
00416
00417
00418
00419 static BOOL initiate_node_status_packet( struct packet_struct *packet )
00420 {
00421 struct nmb_packet *nmb = &packet->packet.nmb;
00422
00423 nmb->header.opcode = NMB_NAME_QUERY_OPCODE;
00424 nmb->header.arcount = 0;
00425
00426 nmb->header.nm_flags.recursion_desired = False;
00427
00428 nmb->question.question_type = QUESTION_TYPE_NB_STATUS;
00429
00430 DEBUG(4,("initiate_node_status_packet: sending node status request for name %s to IP %s\n",
00431 nmb_namestr(&nmb->question.question_name),
00432 inet_ntoa(packet->ip)));
00433
00434 return send_netbios_packet( packet );
00435 }
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448 static BOOL assert_check_subnet(struct subnet_record *subrec)
00449 {
00450 if( subrec == remote_broadcast_subnet) {
00451 DEBUG(0,("assert_check_subnet: Attempt to send packet on remote broadcast subnet. \
00452 This is a bug.\n"));
00453 return True;
00454 }
00455 return False;
00456 }
00457
00458
00459
00460
00461
00462 struct response_record *queue_register_name( struct subnet_record *subrec,
00463 response_function resp_fn,
00464 timeout_response_function timeout_fn,
00465 register_name_success_function success_fn,
00466 register_name_fail_function fail_fn,
00467 struct userdata_struct *userdata,
00468 struct nmb_name *nmbname,
00469 uint16 nb_flags)
00470 {
00471 struct packet_struct *p;
00472 struct response_record *rrec;
00473
00474 if(assert_check_subnet(subrec))
00475 return NULL;
00476
00477
00478 if ((p = create_and_init_netbios_packet(nmbname, (subrec != unicast_subnet), True,
00479 subrec->bcast_ip)) == NULL)
00480 return NULL;
00481
00482 if(initiate_name_register_packet( p, nb_flags, iface_ip(subrec->bcast_ip)) == False) {
00483 p->locked = False;
00484 free_packet(p);
00485 return NULL;
00486 }
00487
00488 if((rrec = make_response_record(subrec,
00489 p,
00490 resp_fn,
00491 timeout_fn,
00492 (success_function)success_fn,
00493 (fail_function)fail_fn,
00494 userdata)) == NULL) {
00495 p->locked = False;
00496 free_packet(p);
00497 return NULL;
00498 }
00499
00500 return rrec;
00501 }
00502
00503
00504
00505
00506
00507 void queue_wins_refresh(struct nmb_name *nmbname,
00508 response_function resp_fn,
00509 timeout_response_function timeout_fn,
00510 uint16 nb_flags,
00511 struct in_addr refresh_ip,
00512 const char *tag)
00513 {
00514 struct packet_struct *p;
00515 struct response_record *rrec;
00516 struct in_addr wins_ip;
00517 struct userdata_struct *userdata;
00518 fstring ip_str;
00519
00520 wins_ip = wins_srv_ip_tag(tag, refresh_ip);
00521
00522 if ((p = create_and_init_netbios_packet(nmbname, False, False, wins_ip)) == NULL) {
00523 return;
00524 }
00525
00526 if (!initiate_name_refresh_packet(p, nb_flags, &refresh_ip)) {
00527 p->locked = False;
00528 free_packet(p);
00529 return;
00530 }
00531
00532 fstrcpy(ip_str, inet_ntoa(refresh_ip));
00533
00534 DEBUG(6,("Refreshing name %s IP %s with WINS server %s using tag '%s'\n",
00535 nmb_namestr(nmbname), ip_str, inet_ntoa(wins_ip), tag));
00536
00537 userdata = (struct userdata_struct *)SMB_MALLOC(sizeof(*userdata) + strlen(tag) + 1);
00538 if (!userdata) {
00539 p->locked = False;
00540 free_packet(p);
00541 DEBUG(0,("Failed to allocate userdata structure!\n"));
00542 return;
00543 }
00544 ZERO_STRUCTP(userdata);
00545 userdata->userdata_len = strlen(tag) + 1;
00546 strlcpy(userdata->data, tag, userdata->userdata_len);
00547
00548 if ((rrec = make_response_record(unicast_subnet,
00549 p,
00550 resp_fn, timeout_fn,
00551 NULL,
00552 NULL,
00553 userdata)) == NULL) {
00554 p->locked = False;
00555 free_packet(p);
00556 return;
00557 }
00558
00559 free(userdata);
00560
00561
00562 rrec->repeat_count = 0;
00563 }
00564
00565
00566
00567
00568
00569
00570 struct response_record *queue_register_multihomed_name( struct subnet_record *subrec,
00571 response_function resp_fn,
00572 timeout_response_function timeout_fn,
00573 register_name_success_function success_fn,
00574 register_name_fail_function fail_fn,
00575 struct userdata_struct *userdata,
00576 struct nmb_name *nmbname,
00577 uint16 nb_flags,
00578 struct in_addr register_ip,
00579 struct in_addr wins_ip)
00580 {
00581 struct packet_struct *p;
00582 struct response_record *rrec;
00583 BOOL ret;
00584
00585
00586 if(subrec != unicast_subnet) {
00587 DEBUG(0,("queue_register_multihomed_name: should only be done on \
00588 unicast subnet. subnet is %s\n.", subrec->subnet_name ));
00589 return NULL;
00590 }
00591
00592 if(assert_check_subnet(subrec))
00593 return NULL;
00594
00595 if ((p = create_and_init_netbios_packet(nmbname, False, True, wins_ip)) == NULL)
00596 return NULL;
00597
00598 if (nb_flags & NB_GROUP)
00599 ret = initiate_name_register_packet( p, nb_flags, ®ister_ip);
00600 else
00601 ret = initiate_multihomed_name_register_packet(p, nb_flags, ®ister_ip);
00602
00603 if (ret == False) {
00604 p->locked = False;
00605 free_packet(p);
00606 return NULL;
00607 }
00608
00609 if ((rrec = make_response_record(subrec,
00610 p,
00611 resp_fn,
00612 timeout_fn,
00613 (success_function)success_fn,
00614 (fail_function)fail_fn,
00615 userdata)) == NULL) {
00616 p->locked = False;
00617 free_packet(p);
00618 return NULL;
00619 }
00620
00621 return rrec;
00622 }
00623
00624
00625
00626
00627
00628 struct response_record *queue_release_name( struct subnet_record *subrec,
00629 response_function resp_fn,
00630 timeout_response_function timeout_fn,
00631 release_name_success_function success_fn,
00632 release_name_fail_function fail_fn,
00633 struct userdata_struct *userdata,
00634 struct nmb_name *nmbname,
00635 uint16 nb_flags,
00636 struct in_addr release_ip,
00637 struct in_addr dest_ip)
00638 {
00639 struct packet_struct *p;
00640 struct response_record *rrec;
00641
00642 if(assert_check_subnet(subrec))
00643 return NULL;
00644
00645 if ((p = create_and_init_netbios_packet(nmbname, (subrec != unicast_subnet), False, dest_ip)) == NULL)
00646 return NULL;
00647
00648 if(initiate_name_release_packet( p, nb_flags, &release_ip) == False) {
00649 p->locked = False;
00650 free_packet(p);
00651 return NULL;
00652 }
00653
00654 if((rrec = make_response_record(subrec,
00655 p,
00656 resp_fn,
00657 timeout_fn,
00658 (success_function)success_fn,
00659 (fail_function)fail_fn,
00660 userdata)) == NULL) {
00661 p->locked = False;
00662 free_packet(p);
00663 return NULL;
00664 }
00665
00666
00667
00668
00669
00670
00671 if (subrec != unicast_subnet) {
00672 rrec->repeat_count = 0;
00673 rrec->repeat_time = 0;
00674 }
00675
00676 return rrec;
00677 }
00678
00679
00680
00681
00682
00683 struct response_record *queue_query_name( struct subnet_record *subrec,
00684 response_function resp_fn,
00685 timeout_response_function timeout_fn,
00686 query_name_success_function success_fn,
00687 query_name_fail_function fail_fn,
00688 struct userdata_struct *userdata,
00689 struct nmb_name *nmbname)
00690 {
00691 struct packet_struct *p;
00692 struct response_record *rrec;
00693 struct in_addr to_ip;
00694
00695 if(assert_check_subnet(subrec))
00696 return NULL;
00697
00698 to_ip = subrec->bcast_ip;
00699
00700
00701
00702 if (subrec->type == UNICAST_SUBNET && is_zero_ip(to_ip)) {
00703
00704
00705
00706
00707
00708
00709 char **tags = wins_srv_tags();
00710 if (!tags) {
00711 return NULL;
00712 }
00713 to_ip = wins_srv_ip_tag(tags[0], to_ip);
00714 wins_srv_tags_free(tags);
00715 }
00716
00717 if(( p = create_and_init_netbios_packet(nmbname,
00718 (subrec != unicast_subnet),
00719 (subrec == unicast_subnet),
00720 to_ip)) == NULL)
00721 return NULL;
00722
00723 if(lp_bind_interfaces_only()) {
00724 int i;
00725
00726 DEBUG(10,("queue_query_name: bind_interfaces_only is set, looking for suitable source IP\n"));
00727 for(i = 0; i < iface_count(); i++) {
00728 struct in_addr *ifip = iface_n_ip(i);
00729
00730 if(ifip == NULL) {
00731 DEBUG(0,("queue_query_name: interface %d has NULL IP address !\n", i));
00732 continue;
00733 }
00734
00735 if (ip_equal(*ifip,loopback_ip)) {
00736 DEBUG(5,("queue_query_name: ignoring loopback interface (%d)\n", i));
00737 continue;
00738 }
00739
00740 DEBUG(10,("queue_query_name: using source IP %s\n",inet_ntoa(*ifip)));
00741 p->fd = find_subnet_fd_for_address( *ifip );
00742 break;
00743 }
00744 }
00745
00746 if(initiate_name_query_packet( p ) == False) {
00747 p->locked = False;
00748 free_packet(p);
00749 return NULL;
00750 }
00751
00752 if((rrec = make_response_record(subrec,
00753 p,
00754 resp_fn,
00755 timeout_fn,
00756 (success_function)success_fn,
00757 (fail_function)fail_fn,
00758 userdata)) == NULL) {
00759 p->locked = False;
00760 free_packet(p);
00761 return NULL;
00762 }
00763
00764 return rrec;
00765 }
00766
00767
00768
00769
00770
00771 struct response_record *queue_query_name_from_wins_server( struct in_addr to_ip,
00772 response_function resp_fn,
00773 timeout_response_function timeout_fn,
00774 query_name_success_function success_fn,
00775 query_name_fail_function fail_fn,
00776 struct userdata_struct *userdata,
00777 struct nmb_name *nmbname)
00778 {
00779 struct packet_struct *p;
00780 struct response_record *rrec;
00781
00782 if ((p = create_and_init_netbios_packet(nmbname, False, False, to_ip)) == NULL)
00783 return NULL;
00784
00785 if(initiate_name_query_packet_from_wins_server( p ) == False) {
00786 p->locked = False;
00787 free_packet(p);
00788 return NULL;
00789 }
00790
00791 if((rrec = make_response_record(wins_server_subnet,
00792 p,
00793 resp_fn,
00794 timeout_fn,
00795 (success_function)success_fn,
00796 (fail_function)fail_fn,
00797 userdata)) == NULL) {
00798 p->locked = False;
00799 free_packet(p);
00800 return NULL;
00801 }
00802
00803 return rrec;
00804 }
00805
00806
00807
00808
00809
00810 struct response_record *queue_node_status( struct subnet_record *subrec,
00811 response_function resp_fn,
00812 timeout_response_function timeout_fn,
00813 node_status_success_function success_fn,
00814 node_status_fail_function fail_fn,
00815 struct userdata_struct *userdata,
00816 struct nmb_name *nmbname,
00817 struct in_addr send_ip)
00818 {
00819 struct packet_struct *p;
00820 struct response_record *rrec;
00821
00822
00823 if(subrec != unicast_subnet) {
00824 DEBUG(0,("queue_register_multihomed_name: should only be done on \
00825 unicast subnet. subnet is %s\n.", subrec->subnet_name ));
00826 return NULL;
00827 }
00828
00829 if(assert_check_subnet(subrec))
00830 return NULL;
00831
00832 if(( p = create_and_init_netbios_packet(nmbname, False, False, send_ip)) == NULL)
00833 return NULL;
00834
00835 if(initiate_node_status_packet(p) == False) {
00836 p->locked = False;
00837 free_packet(p);
00838 return NULL;
00839 }
00840
00841 if((rrec = make_response_record(subrec,
00842 p,
00843 resp_fn,
00844 timeout_fn,
00845 (success_function)success_fn,
00846 (fail_function)fail_fn,
00847 userdata)) == NULL) {
00848 p->locked = False;
00849 free_packet(p);
00850 return NULL;
00851 }
00852
00853 return rrec;
00854 }
00855
00856
00857
00858
00859
00860 void reply_netbios_packet(struct packet_struct *orig_packet,
00861 int rcode, enum netbios_reply_type_code rcv_code, int opcode,
00862 int ttl, char *data,int len)
00863 {
00864 struct packet_struct packet;
00865 struct nmb_packet *nmb = NULL;
00866 struct res_rec answers;
00867 struct nmb_packet *orig_nmb = &orig_packet->packet.nmb;
00868 BOOL loopback_this_packet = False;
00869 int rr_type = RR_TYPE_NB;
00870 const char *packet_type = "unknown";
00871
00872
00873 if(ismyip(orig_packet->ip) && (orig_packet->port == global_nmb_port))
00874 loopback_this_packet = True;
00875
00876 nmb = &packet.packet.nmb;
00877
00878
00879
00880 packet = *orig_packet;
00881 packet.locked = False;
00882 nmb->answers = NULL;
00883 nmb->nsrecs = NULL;
00884 nmb->additional = NULL;
00885
00886 switch (rcv_code) {
00887 case NMB_STATUS:
00888 packet_type = "nmb_status";
00889 nmb->header.nm_flags.recursion_desired = False;
00890 nmb->header.nm_flags.recursion_available = False;
00891 rr_type = RR_TYPE_NBSTAT;
00892 break;
00893 case NMB_QUERY:
00894 packet_type = "nmb_query";
00895 nmb->header.nm_flags.recursion_desired = True;
00896 nmb->header.nm_flags.recursion_available = True;
00897 if (rcode) {
00898 rr_type = RR_TYPE_NULL;
00899 }
00900 break;
00901 case NMB_REG:
00902 case NMB_REG_REFRESH:
00903 packet_type = "nmb_reg";
00904 nmb->header.nm_flags.recursion_desired = True;
00905 nmb->header.nm_flags.recursion_available = True;
00906 break;
00907 case NMB_REL:
00908 packet_type = "nmb_rel";
00909 nmb->header.nm_flags.recursion_desired = False;
00910 nmb->header.nm_flags.recursion_available = False;
00911 break;
00912 case NMB_WAIT_ACK:
00913 packet_type = "nmb_wack";
00914 nmb->header.nm_flags.recursion_desired = False;
00915 nmb->header.nm_flags.recursion_available = False;
00916 rr_type = RR_TYPE_NULL;
00917 break;
00918 case WINS_REG:
00919 packet_type = "wins_reg";
00920 nmb->header.nm_flags.recursion_desired = True;
00921 nmb->header.nm_flags.recursion_available = True;
00922 break;
00923 case WINS_QUERY:
00924 packet_type = "wins_query";
00925 nmb->header.nm_flags.recursion_desired = True;
00926 nmb->header.nm_flags.recursion_available = True;
00927 if (rcode) {
00928 rr_type = RR_TYPE_NULL;
00929 }
00930 break;
00931 default:
00932 DEBUG(0,("reply_netbios_packet: Unknown packet type: %s %s to ip %s\n",
00933 packet_type, nmb_namestr(&orig_nmb->question.question_name),
00934 inet_ntoa(packet.ip)));
00935 return;
00936 }
00937
00938 DEBUG(4,("reply_netbios_packet: sending a reply of packet type: %s %s to ip %s \
00939 for id %hu\n", packet_type, nmb_namestr(&orig_nmb->question.question_name),
00940 inet_ntoa(packet.ip), orig_nmb->header.name_trn_id));
00941
00942 nmb->header.name_trn_id = orig_nmb->header.name_trn_id;
00943 nmb->header.opcode = opcode;
00944 nmb->header.response = True;
00945 nmb->header.nm_flags.bcast = False;
00946 nmb->header.nm_flags.trunc = False;
00947 nmb->header.nm_flags.authoritative = True;
00948
00949 nmb->header.rcode = rcode;
00950 nmb->header.qdcount = 0;
00951 nmb->header.ancount = 1;
00952 nmb->header.nscount = 0;
00953 nmb->header.arcount = 0;
00954
00955 memset((char*)&nmb->question,'\0',sizeof(nmb->question));
00956
00957 nmb->answers = &answers;
00958 memset((char*)nmb->answers,'\0',sizeof(*nmb->answers));
00959
00960 nmb->answers->rr_name = orig_nmb->question.question_name;
00961 nmb->answers->rr_type = rr_type;
00962 nmb->answers->rr_class = RR_CLASS_IN;
00963 nmb->answers->ttl = ttl;
00964
00965 if (data && len) {
00966 if (len < 0 || len > sizeof(nmb->answers->rdata)) {
00967 DEBUG(5,("reply_netbios_packet: "
00968 "invalid packet len (%d)\n",
00969 len ));
00970 return;
00971 }
00972 nmb->answers->rdlength = len;
00973 memcpy(nmb->answers->rdata, data, len);
00974 }
00975
00976 packet.packet_type = NMB_PACKET;
00977
00978
00979 packet.fd = orig_packet->fd;
00980 packet.timestamp = time(NULL);
00981
00982 debug_nmb_packet(&packet);
00983
00984 if(loopback_this_packet) {
00985 struct packet_struct *lo_packet;
00986 DEBUG(5,("reply_netbios_packet: sending packet to ourselves.\n"));
00987 if((lo_packet = copy_packet(&packet)) == NULL)
00988 return;
00989 queue_packet(lo_packet);
00990 } else if (!send_packet(&packet)) {
00991 DEBUG(0,("reply_netbios_packet: send_packet to IP %s port %d failed\n",
00992 inet_ntoa(packet.ip),packet.port));
00993 }
00994 }
00995
00996
00997
00998
00999
01000 static void queue_packet(struct packet_struct *packet)
01001 {
01002 struct packet_struct *p;
01003
01004 if (!packet_queue) {
01005 packet->prev = NULL;
01006 packet->next = NULL;
01007 packet_queue = packet;
01008 return;
01009 }
01010
01011
01012 for (p=packet_queue;p->next;p=p->next)
01013 ;
01014
01015 p->next = packet;
01016 packet->next = NULL;
01017 packet->prev = p;
01018 }
01019
01020
01021
01022
01023
01024 static struct subnet_record *find_subnet_for_dgram_browse_packet(struct packet_struct *p)
01025 {
01026 struct subnet_record *subrec;
01027
01028
01029 for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
01030 if(same_net(p->ip, subrec->bcast_ip, subrec->mask_ip))
01031 return subrec;
01032 }
01033
01034
01035
01036
01037
01038
01039
01040
01041 return FIRST_SUBNET;
01042 }
01043
01044
01045
01046
01047
01048 static void process_browse_packet(struct packet_struct *p, char *buf,int len)
01049 {
01050 struct dgram_packet *dgram = &p->packet.dgram;
01051 int command = CVAL(buf,0);
01052 struct subnet_record *subrec = find_subnet_for_dgram_browse_packet(p);
01053 char scope[64];
01054 unstring src_name;
01055
01056
01057 pull_ascii(scope, dgram->dest_name.scope, 64, 64, STR_TERMINATE);
01058 if (!strequal(scope, global_scope())) {
01059 DEBUG(7,("process_browse_packet: Discarding datagram from IP %s. Scope (%s) \
01060 mismatch with our scope (%s).\n", inet_ntoa(p->ip), scope, global_scope()));
01061 return;
01062 }
01063
01064 pull_ascii_nstring(src_name, sizeof(src_name), dgram->source_name.name);
01065 if (is_myname(src_name)) {
01066 DEBUG(0,("process_browse_packet: Discarding datagram from IP %s. Source name \
01067 %s is one of our names !\n", inet_ntoa(p->ip), nmb_namestr(&dgram->source_name)));
01068 return;
01069 }
01070
01071 switch (command) {
01072 case ANN_HostAnnouncement:
01073 debug_browse_data(buf, len);
01074 process_host_announce(subrec, p, buf+1);
01075 break;
01076 case ANN_DomainAnnouncement:
01077 debug_browse_data(buf, len);
01078 process_workgroup_announce(subrec, p, buf+1);
01079 break;
01080 case ANN_LocalMasterAnnouncement:
01081 debug_browse_data(buf, len);
01082 process_local_master_announce(subrec, p, buf+1);
01083 break;
01084 case ANN_AnnouncementRequest:
01085 debug_browse_data(buf, len);
01086 process_announce_request(subrec, p, buf+1);
01087 break;
01088 case ANN_Election:
01089 debug_browse_data(buf, len);
01090 process_election(subrec, p, buf+1);
01091 break;
01092 case ANN_GetBackupListReq:
01093 debug_browse_data(buf, len);
01094 process_get_backup_list_request(subrec, p, buf+1);
01095 break;
01096 case ANN_GetBackupListResp:
01097 debug_browse_data(buf, len);
01098
01099 DEBUG(0,("process_browse_packet: Discarding GetBackupListResponse \
01100 packet from %s IP %s\n", nmb_namestr(&dgram->source_name), inet_ntoa(p->ip)));
01101 break;
01102 case ANN_ResetBrowserState:
01103 debug_browse_data(buf, len);
01104 process_reset_browser(subrec, p, buf+1);
01105 break;
01106 case ANN_MasterAnnouncement:
01107
01108 subrec = unicast_subnet;
01109
01110 debug_browse_data(buf, len);
01111 process_master_browser_announce(subrec, p, buf+1);
01112 break;
01113 case ANN_BecomeBackup:
01114
01115
01116
01117 debug_browse_data(buf, len);
01118 DEBUG(10,("process_browse_packet: On subnet %s ignoring browse packet \
01119 command ANN_BecomeBackup from %s IP %s to %s\n", subrec->subnet_name, nmb_namestr(&dgram->source_name),
01120 inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
01121 break;
01122 default:
01123 debug_browse_data(buf, len);
01124 DEBUG(0,("process_browse_packet: On subnet %s ignoring browse packet \
01125 command code %d from %s IP %s to %s\n", subrec->subnet_name, command, nmb_namestr(&dgram->source_name),
01126 inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
01127 break;
01128 }
01129 }
01130
01131
01132
01133
01134
01135 static void process_lanman_packet(struct packet_struct *p, char *buf,int len)
01136 {
01137 struct dgram_packet *dgram = &p->packet.dgram;
01138 int command = SVAL(buf,0);
01139 struct subnet_record *subrec = find_subnet_for_dgram_browse_packet(p);
01140 char scope[64];
01141 unstring src_name;
01142
01143
01144
01145 pull_ascii(scope, dgram->dest_name.scope, 64, 64, STR_TERMINATE);
01146 if (!strequal(scope, global_scope())) {
01147 DEBUG(7,("process_lanman_packet: Discarding datagram from IP %s. Scope (%s) \
01148 mismatch with our scope (%s).\n", inet_ntoa(p->ip), scope, global_scope()));
01149 return;
01150 }
01151
01152 pull_ascii_nstring(src_name, sizeof(src_name), dgram->source_name.name);
01153 if (is_myname(src_name)) {
01154 DEBUG(0,("process_lanman_packet: Discarding datagram from IP %s. Source name \
01155 %s is one of our names !\n", inet_ntoa(p->ip), nmb_namestr(&dgram->source_name)));
01156 return;
01157 }
01158
01159 switch (command) {
01160 case ANN_HostAnnouncement:
01161 debug_browse_data(buf, len);
01162 process_lm_host_announce(subrec, p, buf+1, len > 1 ? len-1 : 0);
01163 break;
01164 case ANN_AnnouncementRequest:
01165 process_lm_announce_request(subrec, p, buf+1, len > 1 ? len-1 : 0);
01166 break;
01167 default:
01168 DEBUG(0,("process_lanman_packet: On subnet %s ignoring browse packet \
01169 command code %d from %s IP %s to %s\n", subrec->subnet_name, command, nmb_namestr(&dgram->source_name),
01170 inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
01171 break;
01172 }
01173 }
01174
01175
01176
01177
01178
01179
01180
01181 static BOOL listening(struct packet_struct *p,struct nmb_name *nbname)
01182 {
01183 struct subnet_record *subrec = NULL;
01184
01185 for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
01186 if(same_net(p->ip, subrec->bcast_ip, subrec->mask_ip))
01187 break;
01188 }
01189
01190 if(subrec == NULL)
01191 subrec = unicast_subnet;
01192
01193 return (find_name_on_subnet(subrec, nbname, FIND_SELF_NAME) != NULL);
01194 }
01195
01196
01197
01198
01199
01200 static void process_dgram(struct packet_struct *p)
01201 {
01202 char *buf;
01203 char *buf2;
01204 int len;
01205 struct dgram_packet *dgram = &p->packet.dgram;
01206
01207
01208 if (!listening(p,&dgram->dest_name)) {
01209 unexpected_packet(p);
01210 DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s from %s\n",
01211 nmb_namestr(&dgram->dest_name), inet_ntoa(p->ip)));
01212 return;
01213 }
01214
01215 if (dgram->header.msg_type != 0x10 && dgram->header.msg_type != 0x11 && dgram->header.msg_type != 0x12) {
01216 unexpected_packet(p);
01217
01218 DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s from IP %s as it is \
01219 an error packet of type %x\n", nmb_namestr(&dgram->dest_name), inet_ntoa(p->ip), dgram->header.msg_type));
01220 return;
01221 }
01222
01223
01224 if (dgram->datasize < (smb_vwv12 - 2)) {
01225
01226 DEBUG(0,("process_dgram: ignoring too short dgram packet (%u) sent to name %s from IP %s\n",
01227 (unsigned int)dgram->datasize,
01228 nmb_namestr(&dgram->dest_name),
01229 inet_ntoa(p->ip) ));
01230 return;
01231 }
01232
01233 buf = &dgram->data[0];
01234 buf -= 4;
01235
01236 if (CVAL(buf,smb_com) != SMBtrans)
01237 return;
01238
01239 len = SVAL(buf,smb_vwv11);
01240 buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
01241
01242 if (len <= 0 || len > dgram->datasize) {
01243 DEBUG(0,("process_dgram: ignoring malformed1 (datasize = %d, len = %d) datagram \
01244 packet sent to name %s from IP %s\n",
01245 dgram->datasize,
01246 len,
01247 nmb_namestr(&dgram->dest_name),
01248 inet_ntoa(p->ip) ));
01249 return;
01250 }
01251
01252 if (buf2 < dgram->data || (buf2 >= dgram->data + dgram->datasize)) {
01253 DEBUG(0,("process_dgram: ignoring malformed2 (datasize = %d, len=%d, off=%d) datagram \
01254 packet sent to name %s from IP %s\n",
01255 dgram->datasize,
01256 len,
01257 (int)PTR_DIFF(buf2, dgram->data),
01258 nmb_namestr(&dgram->dest_name),
01259 inet_ntoa(p->ip) ));
01260 return;
01261 }
01262
01263 if ((buf2 + len < dgram->data) || (buf2 + len > dgram->data + dgram->datasize)) {
01264 DEBUG(0,("process_dgram: ignoring malformed3 (datasize = %d, len=%d, off=%d) datagram \
01265 packet sent to name %s from IP %s\n",
01266 dgram->datasize,
01267 len,
01268 (int)PTR_DIFF(buf2, dgram->data),
01269 nmb_namestr(&dgram->dest_name),
01270 inet_ntoa(p->ip) ));
01271 return;
01272 }
01273
01274 DEBUG(4,("process_dgram: datagram from %s to %s IP %s for %s of type %d len=%d\n",
01275 nmb_namestr(&dgram->source_name),nmb_namestr(&dgram->dest_name),
01276 inet_ntoa(p->ip), smb_buf(buf),CVAL(buf2,0),len));
01277
01278
01279 if (strequal(smb_buf(buf),BROWSE_MAILSLOT)) {
01280 process_browse_packet(p,buf2,len);
01281 return;
01282 }
01283
01284
01285 if (strequal(smb_buf(buf),LANMAN_MAILSLOT)) {
01286 process_lanman_packet(p,buf2,len);
01287 return;
01288 }
01289
01290
01291 if (strequal(smb_buf(buf),NET_LOGON_MAILSLOT)) {
01292 process_logon_packet(p,buf2,len,NET_LOGON_MAILSLOT);
01293 return;
01294 }
01295
01296
01297 if (strequal(smb_buf(buf),NT_LOGON_MAILSLOT)) {
01298 process_logon_packet(p,buf2,len,NT_LOGON_MAILSLOT);
01299 return;
01300 }
01301
01302 unexpected_packet(p);
01303 }
01304
01305
01306
01307
01308
01309 static BOOL validate_nmb_response_packet( struct nmb_packet *nmb )
01310 {
01311 BOOL ignore = False;
01312
01313 switch (nmb->header.opcode) {
01314 case NMB_NAME_REG_OPCODE:
01315 case NMB_NAME_REFRESH_OPCODE_8:
01316 case NMB_NAME_REFRESH_OPCODE_9:
01317 if (nmb->header.ancount == 0) {
01318 DEBUG(0,("validate_nmb_response_packet: Bad REG/REFRESH Packet. "));
01319 ignore = True;
01320 }
01321 break;
01322
01323 case NMB_NAME_QUERY_OPCODE:
01324 if ((nmb->header.ancount != 0) && (nmb->header.ancount != 1)) {
01325 DEBUG(0,("validate_nmb_response_packet: Bad QUERY Packet. "));
01326 ignore = True;
01327 }
01328 break;
01329
01330 case NMB_NAME_RELEASE_OPCODE:
01331 if (nmb->header.ancount == 0) {
01332 DEBUG(0,("validate_nmb_response_packet: Bad RELEASE Packet. "));
01333 ignore = True;
01334 }
01335 break;
01336
01337 case NMB_WACK_OPCODE:
01338
01339 if (nmb->header.ancount != 1) {
01340 DEBUG(0,("validate_nmb_response_packet: Bad WACK Packet. "));
01341 ignore = True;
01342 }
01343 break;
01344 default:
01345 DEBUG(0,("validate_nmb_response_packet: Ignoring packet with unknown opcode %d.\n",
01346 nmb->header.opcode));
01347 return True;
01348 }
01349
01350 if(ignore)
01351 DEBUG(0,("Ignoring response packet with opcode %d.\n", nmb->header.opcode));
01352
01353 return ignore;
01354 }
01355
01356
01357
01358
01359
01360 static BOOL validate_nmb_packet( struct nmb_packet *nmb )
01361 {
01362 BOOL ignore = False;
01363
01364 switch (nmb->header.opcode) {
01365 case NMB_NAME_REG_OPCODE:
01366 case NMB_NAME_REFRESH_OPCODE_8:
01367 case NMB_NAME_REFRESH_OPCODE_9:
01368 case NMB_NAME_MULTIHOMED_REG_OPCODE:
01369 if (nmb->header.qdcount==0 || nmb->header.arcount==0) {
01370 DEBUG(0,("validate_nmb_packet: Bad REG/REFRESH Packet. "));
01371 ignore = True;
01372 }
01373 break;
01374
01375 case NMB_NAME_QUERY_OPCODE:
01376 if ((nmb->header.qdcount == 0) || ((nmb->question.question_type != QUESTION_TYPE_NB_QUERY) &&
01377 (nmb->question.question_type != QUESTION_TYPE_NB_STATUS))) {
01378 DEBUG(0,("validate_nmb_packet: Bad QUERY Packet. "));
01379 ignore = True;
01380 }
01381 break;
01382
01383 case NMB_NAME_RELEASE_OPCODE:
01384 if (nmb->header.qdcount==0 || nmb->header.arcount==0) {
01385 DEBUG(0,("validate_nmb_packet: Bad RELEASE Packet. "));
01386 ignore = True;
01387 }
01388 break;
01389 default:
01390 DEBUG(0,("validate_nmb_packet: Ignoring packet with unknown opcode %d.\n",
01391 nmb->header.opcode));
01392 return True;
01393 }
01394
01395 if(ignore)
01396 DEBUG(0,("validate_nmb_packet: Ignoring request packet with opcode %d.\n", nmb->header.opcode));
01397
01398 return ignore;
01399 }
01400
01401
01402
01403
01404
01405 static struct subnet_record *find_subnet_for_nmb_packet( struct packet_struct *p,
01406 struct response_record **pprrec)
01407 {
01408 struct nmb_packet *nmb = &p->packet.nmb;
01409 struct response_record *rrec = NULL;
01410 struct subnet_record *subrec = NULL;
01411
01412 if(pprrec != NULL)
01413 *pprrec = NULL;
01414
01415 if(nmb->header.response) {
01416
01417
01418 rrec = find_response_record( &subrec, nmb->header.name_trn_id);
01419 if(rrec == NULL) {
01420 DEBUG(3,("find_subnet_for_nmb_packet: response record not found for response id %hu\n",
01421 nmb->header.name_trn_id));
01422 unexpected_packet(p);
01423 return NULL;
01424 }
01425
01426 if(subrec == NULL) {
01427 DEBUG(0,("find_subnet_for_nmb_packet: subnet record not found for response id %hu\n",
01428 nmb->header.name_trn_id));
01429 return NULL;
01430 }
01431
01432 if(pprrec != NULL)
01433 *pprrec = rrec;
01434 return subrec;
01435 }
01436
01437
01438
01439
01440 if(packet_is_for_wins_server(p))
01441 return wins_server_subnet;
01442
01443
01444 if(nmb->header.nm_flags.bcast == False)
01445 return unicast_subnet;
01446
01447
01448 for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
01449 if(same_net(p->ip, subrec->bcast_ip, subrec->mask_ip))
01450 return subrec;
01451 }
01452
01453
01454 return remote_broadcast_subnet;
01455 }
01456
01457
01458
01459
01460
01461 static void process_nmb_request(struct packet_struct *p)
01462 {
01463 struct nmb_packet *nmb = &p->packet.nmb;
01464 struct subnet_record *subrec = NULL;
01465
01466 debug_nmb_packet(p);
01467
01468
01469 if(validate_nmb_packet(nmb))
01470 return;
01471
01472
01473 if((subrec = find_subnet_for_nmb_packet(p, NULL))==NULL)
01474 return;
01475
01476 switch (nmb->header.opcode) {
01477 case NMB_NAME_REG_OPCODE:
01478 if(subrec == wins_server_subnet)
01479 wins_process_name_registration_request(subrec, p);
01480 else
01481 process_name_registration_request(subrec, p);
01482 break;
01483
01484 case NMB_NAME_REFRESH_OPCODE_8:
01485 case NMB_NAME_REFRESH_OPCODE_9:
01486 if(subrec == wins_server_subnet)
01487 wins_process_name_refresh_request(subrec, p);
01488 else
01489 process_name_refresh_request(subrec, p);
01490 break;
01491
01492 case NMB_NAME_MULTIHOMED_REG_OPCODE:
01493 if(subrec == wins_server_subnet) {
01494 wins_process_multihomed_name_registration_request(subrec, p);
01495 } else {
01496 DEBUG(0,("process_nmb_request: Multihomed registration request must be \
01497 directed at a WINS server.\n"));
01498 }
01499 break;
01500
01501 case NMB_NAME_QUERY_OPCODE:
01502 switch (nmb->question.question_type) {
01503 case QUESTION_TYPE_NB_QUERY:
01504 if(subrec == wins_server_subnet)
01505 wins_process_name_query_request(subrec, p);
01506 else
01507 process_name_query_request(subrec, p);
01508 break;
01509 case QUESTION_TYPE_NB_STATUS:
01510 if(subrec == wins_server_subnet) {
01511 DEBUG(0,("process_nmb_request: NB_STATUS request directed at WINS server is \
01512 not allowed.\n"));
01513 break;
01514 } else {
01515 process_node_status_request(subrec, p);
01516 }
01517 break;
01518 }
01519 break;
01520
01521 case NMB_NAME_RELEASE_OPCODE:
01522 if(subrec == wins_server_subnet)
01523 wins_process_name_release_request(subrec, p);
01524 else
01525 process_name_release_request(subrec, p);
01526 break;
01527 }
01528 }
01529
01530
01531
01532
01533
01534
01535 static void process_nmb_response(struct packet_struct *p)
01536 {
01537 struct nmb_packet *nmb = &p->packet.nmb;
01538 struct subnet_record *subrec = NULL;
01539 struct response_record *rrec = NULL;
01540
01541 debug_nmb_packet(p);
01542
01543 if(validate_nmb_response_packet(nmb))
01544 return;
01545
01546 if((subrec = find_subnet_for_nmb_packet(p, &rrec))==NULL)
01547 return;
01548
01549 if(rrec == NULL) {
01550 DEBUG(0,("process_nmb_response: response packet received but no response record \
01551 found for id = %hu. Ignoring packet.\n", nmb->header.name_trn_id));
01552 return;
01553 }
01554
01555
01556 rrec->num_msgs++;
01557
01558 rrec->repeat_count = 0;
01559
01560
01561 (*rrec->resp_fn)(subrec, rrec, p);
01562 }
01563
01564
01565
01566
01567
01568 void run_packet_queue(void)
01569 {
01570 struct packet_struct *p;
01571
01572 while ((p = packet_queue)) {
01573 packet_queue = p->next;
01574 if (packet_queue)
01575 packet_queue->prev = NULL;
01576 p->next = p->prev = NULL;
01577
01578 switch (p->packet_type) {
01579 case NMB_PACKET:
01580 if(p->packet.nmb.header.response)
01581 process_nmb_response(p);
01582 else
01583 process_nmb_request(p);
01584 break;
01585
01586 case DGRAM_PACKET:
01587 process_dgram(p);
01588 break;
01589 }
01590 free_packet(p);
01591 }
01592 }
01593
01594
01595
01596
01597
01598
01599
01600
01601
01602 void retransmit_or_expire_response_records(time_t t)
01603 {
01604 struct subnet_record *subrec;
01605
01606 for (subrec = FIRST_SUBNET; subrec; subrec = get_next_subnet_maybe_unicast_or_wins_server(subrec)) {
01607 struct response_record *rrec, *nextrrec;
01608
01609 restart:
01610
01611 for (rrec = subrec->responselist; rrec; rrec = nextrrec) {
01612 nextrrec = rrec->next;
01613
01614 if (rrec->repeat_time <= t) {
01615 if (rrec->repeat_count > 0) {
01616
01617 if(!send_packet(rrec->packet)) {
01618 DEBUG(0,("retransmit_or_expire_response_records: Failed to resend packet id %hu \
01619 to IP %s on subnet %s\n", rrec->response_id, inet_ntoa(rrec->packet->ip), subrec->subnet_name));
01620 }
01621 rrec->repeat_time = t + rrec->repeat_interval;
01622 rrec->repeat_count--;
01623 } else {
01624 DEBUG(4,("retransmit_or_expire_response_records: timeout for packet id %hu to IP %s \
01625 on subnet %s\n", rrec->response_id, inet_ntoa(rrec->packet->ip), subrec->subnet_name));
01626
01627
01628
01629
01630
01631
01632 if(!rrec->in_expiration_processing) {
01633
01634
01635
01636
01637
01638 rrec->in_expiration_processing = True;
01639
01640
01641
01642 if(rrec->timeout_fn) {
01643 (*rrec->timeout_fn)(subrec, rrec);
01644 } else {
01645
01646
01647 remove_response_record(subrec, rrec);
01648 }
01649
01650
01651 goto restart;
01652 }
01653 }
01654 }
01655 }
01656 }
01657 }
01658
01659
01660
01661
01662
01663
01664 static BOOL create_listen_fdset(fd_set **ppset, int **psock_array, int *listen_number, int *maxfd)
01665 {
01666 int *sock_array = NULL;
01667 struct subnet_record *subrec = NULL;
01668 int count = 0;
01669 int num = 0;
01670 fd_set *pset = SMB_MALLOC_P(fd_set);
01671
01672 if(pset == NULL) {
01673 DEBUG(0,("create_listen_fdset: malloc fail !\n"));
01674 return True;
01675 }
01676
01677
01678 for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
01679 count++;
01680
01681 if((count*2) + 2 > FD_SETSIZE) {
01682 DEBUG(0,("create_listen_fdset: Too many file descriptors needed (%d). We can \
01683 only use %d.\n", (count*2) + 2, FD_SETSIZE));
01684 SAFE_FREE(pset);
01685 return True;
01686 }
01687
01688 if((sock_array = SMB_MALLOC_ARRAY(int, (count*2) + 2)) == NULL) {
01689 DEBUG(0,("create_listen_fdset: malloc fail for socket array.\n"));
01690 SAFE_FREE(pset);
01691 return True;
01692 }
01693
01694 FD_ZERO(pset);
01695
01696
01697 FD_SET(ClientNMB,pset);
01698 sock_array[num++] = ClientNMB;
01699 *maxfd = MAX( *maxfd, ClientNMB);
01700
01701
01702 for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
01703 FD_SET(subrec->nmb_sock,pset);
01704 sock_array[num++] = subrec->nmb_sock;
01705 *maxfd = MAX( *maxfd, subrec->nmb_sock);
01706 }
01707
01708
01709 FD_SET(ClientDGRAM,pset);
01710 sock_array[num++] = ClientDGRAM;
01711 *maxfd = MAX( *maxfd, ClientDGRAM);
01712
01713
01714 for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
01715 FD_SET(subrec->dgram_sock,pset);
01716 sock_array[num++] = subrec->dgram_sock;
01717 *maxfd = MAX( *maxfd, subrec->dgram_sock);
01718 }
01719
01720 *listen_number = (count*2) + 2;
01721
01722 SAFE_FREE(*ppset);
01723 SAFE_FREE(*psock_array);
01724
01725 *ppset = pset;
01726 *psock_array = sock_array;
01727
01728 return False;
01729 }
01730
01731
01732
01733
01734
01735
01736 BOOL listen_for_packets(BOOL run_election)
01737 {
01738 static fd_set *listen_set = NULL;
01739 static int listen_number = 0;
01740 static int *sock_array = NULL;
01741 int i;
01742 static int maxfd = 0;
01743
01744 fd_set fds;
01745 int selrtn;
01746 struct timeval timeout;
01747 #ifndef SYNC_DNS
01748 int dns_fd;
01749 #endif
01750
01751 if(listen_set == NULL || rescan_listen_set) {
01752 if(create_listen_fdset(&listen_set, &sock_array, &listen_number, &maxfd)) {
01753 DEBUG(0,("listen_for_packets: Fatal error. unable to create listen set. Exiting.\n"));
01754 return True;
01755 }
01756 rescan_listen_set = False;
01757 }
01758
01759 memcpy((char *)&fds, (char *)listen_set, sizeof(fd_set));
01760
01761 #ifndef SYNC_DNS
01762 dns_fd = asyncdns_fd();
01763 if (dns_fd != -1) {
01764 FD_SET(dns_fd, &fds);
01765 maxfd = MAX( maxfd, dns_fd);
01766 }
01767 #endif
01768
01769
01770
01771
01772
01773
01774
01775
01776 timeout.tv_sec = (run_election||num_response_packets) ? 1 : NMBD_SELECT_LOOP;
01777 timeout.tv_usec = 0;
01778
01779
01780
01781 BlockSignals(False, SIGTERM);
01782
01783 selrtn = sys_select(maxfd+1,&fds,NULL,NULL,&timeout);
01784
01785
01786
01787 BlockSignals(True, SIGTERM);
01788
01789 if(selrtn == -1) {
01790 return False;
01791 }
01792
01793 #ifndef SYNC_DNS
01794 if (dns_fd != -1 && FD_ISSET(dns_fd,&fds)) {
01795 run_dns_queue();
01796 }
01797 #endif
01798
01799 for(i = 0; i < listen_number; i++) {
01800 if (i < (listen_number/2)) {
01801
01802 if (FD_ISSET(sock_array[i],&fds)) {
01803 struct packet_struct *packet = read_packet(sock_array[i], NMB_PACKET);
01804 if (packet) {
01805
01806
01807
01808
01809 if(lp_bind_interfaces_only() && (sock_array[i] == ClientNMB) &&
01810 (!is_local_net(packet->ip))) {
01811 DEBUG(7,("discarding nmb packet sent to broadcast socket from %s:%d\n",
01812 inet_ntoa(packet->ip),packet->port));
01813 free_packet(packet);
01814 } else if ((ip_equal(loopback_ip, packet->ip) ||
01815 ismyip(packet->ip)) && packet->port == global_nmb_port &&
01816 packet->packet.nmb.header.nm_flags.bcast) {
01817 DEBUG(7,("discarding own bcast packet from %s:%d\n",
01818 inet_ntoa(packet->ip),packet->port));
01819 free_packet(packet);
01820 } else {
01821
01822 packet->fd = sock_array[i];
01823 queue_packet(packet);
01824 }
01825 }
01826 }
01827 } else {
01828
01829 if (FD_ISSET(sock_array[i],&fds)) {
01830 struct packet_struct *packet = read_packet(sock_array[i], DGRAM_PACKET);
01831 if (packet) {
01832
01833
01834
01835
01836 if(lp_bind_interfaces_only() && (sock_array[i] == ClientDGRAM) &&
01837 (!is_local_net(packet->ip))) {
01838 DEBUG(7,("discarding dgram packet sent to broadcast socket from %s:%d\n",
01839 inet_ntoa(packet->ip),packet->port));
01840 free_packet(packet);
01841 } else if ((ip_equal(loopback_ip, packet->ip) ||
01842 ismyip(packet->ip)) && packet->port == DGRAM_PORT) {
01843 DEBUG(7,("discarding own dgram packet from %s:%d\n",
01844 inet_ntoa(packet->ip),packet->port));
01845 free_packet(packet);
01846 } else {
01847
01848 packet->fd = sock_array[i];
01849 queue_packet(packet);
01850 }
01851 }
01852 }
01853 }
01854 }
01855 return False;
01856 }
01857
01858
01859
01860
01861
01862 BOOL send_mailslot(BOOL unique, const char *mailslot,char *buf, size_t len,
01863 const char *srcname, int src_type,
01864 const char *dstname, int dest_type,
01865 struct in_addr dest_ip,struct in_addr src_ip,
01866 int dest_port)
01867 {
01868 BOOL loopback_this_packet = False;
01869 struct packet_struct p;
01870 struct dgram_packet *dgram = &p.packet.dgram;
01871 char *ptr,*p2;
01872 char tmp[4];
01873
01874 memset((char *)&p,'\0',sizeof(p));
01875
01876 if(ismyip(dest_ip) && (dest_port == DGRAM_PORT))
01877 loopback_this_packet = True;
01878
01879
01880
01881
01882 dgram->header.msg_type = unique ? 0x10 : 0x11;
01883 dgram->header.flags.node_type = M_NODE;
01884 dgram->header.flags.first = True;
01885 dgram->header.flags.more = False;
01886 dgram->header.dgm_id = generate_name_trn_id();
01887 dgram->header.source_ip = src_ip;
01888 dgram->header.source_port = DGRAM_PORT;
01889 dgram->header.dgm_length = 0;
01890 dgram->header.packet_offset = 0;
01891
01892 make_nmb_name(&dgram->source_name,srcname,src_type);
01893 make_nmb_name(&dgram->dest_name,dstname,dest_type);
01894
01895 ptr = &dgram->data[0];
01896
01897
01898 ptr -= 4;
01899 memcpy(tmp,ptr,4);
01900
01901 if (smb_size + 17*2 + strlen(mailslot) + 1 + len > MAX_DGRAM_SIZE) {
01902 DEBUG(0, ("send_mailslot: Cannot write beyond end of packet\n"));
01903 return False;
01904 }
01905
01906 set_message(ptr,17,strlen(mailslot) + 1 + len,True);
01907 memcpy(ptr,tmp,4);
01908
01909 SCVAL(ptr,smb_com,SMBtrans);
01910 SSVAL(ptr,smb_vwv1,len);
01911 SSVAL(ptr,smb_vwv11,len);
01912 SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
01913 SSVAL(ptr,smb_vwv13,3);
01914 SSVAL(ptr,smb_vwv14,1);
01915 SSVAL(ptr,smb_vwv15,1);
01916 SSVAL(ptr,smb_vwv16,2);
01917 p2 = smb_buf(ptr);
01918 safe_strcpy_base(p2, mailslot, dgram->data, sizeof(dgram->data));
01919 p2 = skip_string(ptr,MAX_DGRAM_SIZE,p2);
01920
01921 if (((p2+len) > dgram->data+sizeof(dgram->data)) || ((p2+len) < p2)) {
01922 DEBUG(0, ("send_mailslot: Cannot write beyond end of packet\n"));
01923 return False;
01924 } else {
01925 memcpy(p2,buf,len);
01926 p2 += len;
01927 }
01928
01929 dgram->datasize = PTR_DIFF(p2,ptr+4);
01930
01931 p.ip = dest_ip;
01932 p.port = dest_port;
01933 p.fd = find_subnet_mailslot_fd_for_address( src_ip );
01934 p.timestamp = time(NULL);
01935 p.packet_type = DGRAM_PACKET;
01936
01937 DEBUG(4,("send_mailslot: Sending to mailslot %s from %s IP %s ", mailslot,
01938 nmb_namestr(&dgram->source_name), inet_ntoa(src_ip)));
01939 DEBUG(4,("to %s IP %s\n", nmb_namestr(&dgram->dest_name), inet_ntoa(dest_ip)));
01940
01941 debug_browse_data(buf, len);
01942
01943 if(loopback_this_packet) {
01944 struct packet_struct *lo_packet = NULL;
01945 DEBUG(5,("send_mailslot: sending packet to ourselves.\n"));
01946 if((lo_packet = copy_packet(&p)) == NULL)
01947 return False;
01948 queue_packet(lo_packet);
01949 return True;
01950 } else {
01951 return(send_packet(&p));
01952 }
01953 }