00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "includes.h"
00027
00028 extern struct in_addr loopback_ip;
00029 extern int global_nmb_port;
00030
00031
00032 struct subnet_record *subnetlist = NULL;
00033
00034
00035
00036
00037 struct subnet_record *unicast_subnet = NULL;
00038 struct subnet_record *remote_broadcast_subnet = NULL;
00039 struct subnet_record *wins_server_subnet = NULL;
00040
00041 extern uint16 samba_nb_type;
00042
00043
00044
00045
00046
00047 static void add_subnet(struct subnet_record *subrec)
00048 {
00049 DLIST_ADD(subnetlist, subrec);
00050 }
00051
00052
00053
00054
00055
00056
00057
00058 void close_subnet(struct subnet_record *subrec)
00059 {
00060 if (subrec->dgram_sock != -1) {
00061 close(subrec->dgram_sock);
00062 subrec->dgram_sock = -1;
00063 }
00064 if (subrec->nmb_sock != -1) {
00065 close(subrec->nmb_sock);
00066 subrec->nmb_sock = -1;
00067 }
00068
00069 DLIST_REMOVE(subnetlist, subrec);
00070 }
00071
00072
00073
00074
00075
00076 static struct subnet_record *make_subnet(const char *name, enum subnet_type type,
00077 struct in_addr myip, struct in_addr bcast_ip,
00078 struct in_addr mask_ip)
00079 {
00080 struct subnet_record *subrec = NULL;
00081 int nmb_sock, dgram_sock;
00082
00083
00084
00085
00086 if(type != NORMAL_SUBNET) {
00087 nmb_sock = -1;
00088 dgram_sock = -1;
00089 } else {
00090
00091
00092
00093
00094
00095
00096 if((nmb_sock = open_socket_in(SOCK_DGRAM, global_nmb_port,0, myip.s_addr,True)) == -1) {
00097 if( DEBUGLVL( 0 ) ) {
00098 Debug1( "nmbd_subnetdb:make_subnet()\n" );
00099 Debug1( " Failed to open nmb socket on interface %s ", inet_ntoa(myip) );
00100 Debug1( "for port %d. ", global_nmb_port );
00101 Debug1( "Error was %s\n", strerror(errno) );
00102 }
00103 return NULL;
00104 }
00105
00106 if((dgram_sock = open_socket_in(SOCK_DGRAM,DGRAM_PORT,3, myip.s_addr,True)) == -1) {
00107 if( DEBUGLVL( 0 ) ) {
00108 Debug1( "nmbd_subnetdb:make_subnet()\n" );
00109 Debug1( " Failed to open dgram socket on interface %s ", inet_ntoa(myip) );
00110 Debug1( "for port %d. ", DGRAM_PORT );
00111 Debug1( "Error was %s\n", strerror(errno) );
00112 }
00113 return NULL;
00114 }
00115
00116
00117 set_socket_options(nmb_sock,"SO_BROADCAST");
00118 set_socket_options(dgram_sock,"SO_BROADCAST");
00119
00120
00121 set_blocking(nmb_sock, False);
00122 set_blocking(dgram_sock, False);
00123 }
00124
00125 subrec = SMB_MALLOC_P(struct subnet_record);
00126 if (!subrec) {
00127 DEBUG(0,("make_subnet: malloc fail !\n"));
00128 close(nmb_sock);
00129 close(dgram_sock);
00130 return(NULL);
00131 }
00132
00133 ZERO_STRUCTP(subrec);
00134
00135 if((subrec->subnet_name = SMB_STRDUP(name)) == NULL) {
00136 DEBUG(0,("make_subnet: malloc fail for subnet name !\n"));
00137 close(nmb_sock);
00138 close(dgram_sock);
00139 ZERO_STRUCTP(subrec);
00140 SAFE_FREE(subrec);
00141 return(NULL);
00142 }
00143
00144 DEBUG(2, ("making subnet name:%s ", name ));
00145 DEBUG(2, ("Broadcast address:%s ", inet_ntoa(bcast_ip)));
00146 DEBUG(2, ("Subnet mask:%s\n", inet_ntoa(mask_ip)));
00147
00148 subrec->namelist_changed = False;
00149 subrec->work_changed = False;
00150
00151 subrec->bcast_ip = bcast_ip;
00152 subrec->mask_ip = mask_ip;
00153 subrec->myip = myip;
00154 subrec->type = type;
00155 subrec->nmb_sock = nmb_sock;
00156 subrec->dgram_sock = dgram_sock;
00157
00158 return subrec;
00159 }
00160
00161
00162
00163
00164
00165 struct subnet_record *make_normal_subnet(struct interface *iface)
00166 {
00167 struct subnet_record *subrec;
00168
00169 subrec = make_subnet(inet_ntoa(iface->ip), NORMAL_SUBNET,
00170 iface->ip, iface->bcast, iface->nmask);
00171 if (subrec) {
00172 add_subnet(subrec);
00173 }
00174 return subrec;
00175 }
00176
00177
00178
00179
00180
00181 BOOL create_subnets(void)
00182 {
00183 int num_interfaces;
00184 int i;
00185 struct in_addr unicast_ip, ipzero;
00186
00187 try_interfaces_again:
00188
00189 if (iface_count_nl() == 0) {
00190 DEBUG(0,("create_subnets: No non-loopback local interfaces !\n"));
00191 DEBUG(0,("create_subnets: Waiting for an interface to appear ...\n"));
00192 }
00193
00194 while (iface_count_nl() == 0) {
00195 void (*saved_handler)(int);
00196
00197
00198
00199
00200
00201
00202 saved_handler = CatchSignal( SIGTERM, SIGNAL_CAST SIG_DFL );
00203
00204 sleep(5);
00205 load_interfaces();
00206
00207
00208
00209
00210
00211 CatchSignal( SIGTERM, SIGNAL_CAST saved_handler );
00212 }
00213
00214 num_interfaces = iface_count();
00215
00216
00217
00218
00219
00220
00221 for (i = 0 ; i < num_interfaces; i++) {
00222 struct interface *iface = get_interface(i);
00223
00224 if (!iface) {
00225 DEBUG(2,("create_subnets: can't get interface %d.\n", i ));
00226 continue;
00227 }
00228
00229
00230
00231
00232
00233
00234
00235 if (ip_equal(iface->ip, loopback_ip)) {
00236 DEBUG(2,("create_subnets: Ignoring loopback interface.\n" ));
00237 continue;
00238 }
00239
00240 if (!make_normal_subnet(iface))
00241 return False;
00242 }
00243
00244
00245 if (subnetlist == NULL) {
00246 void (*saved_handler)(int);
00247
00248 DEBUG(0,("create_subnets: Unable to create any subnet from "
00249 "given interfaces. Is your interface line in "
00250 "smb.conf correct ?\n"));
00251
00252 saved_handler = CatchSignal( SIGTERM, SIGNAL_CAST SIG_DFL );
00253
00254 sleep(5);
00255 load_interfaces();
00256
00257 CatchSignal( SIGTERM, SIGNAL_CAST saved_handler );
00258 goto try_interfaces_again;
00259 }
00260
00261 if (lp_we_are_a_wins_server()) {
00262
00263 struct in_addr *nip = iface_n_ip(0);
00264
00265 if (!nip) {
00266 return False;
00267 }
00268
00269 unicast_ip = *nip;
00270 } else {
00271
00272
00273
00274 zero_ip(&unicast_ip);
00275 }
00276
00277
00278
00279
00280
00281
00282
00283
00284 unicast_subnet = make_subnet( "UNICAST_SUBNET", UNICAST_SUBNET,
00285 unicast_ip, unicast_ip, unicast_ip);
00286
00287 zero_ip(&ipzero);
00288
00289 remote_broadcast_subnet = make_subnet( "REMOTE_BROADCAST_SUBNET",
00290 REMOTE_BROADCAST_SUBNET,
00291 ipzero, ipzero, ipzero);
00292
00293 if((unicast_subnet == NULL) || (remote_broadcast_subnet == NULL))
00294 return False;
00295
00296
00297
00298
00299
00300
00301 if (lp_we_are_a_wins_server()) {
00302 if( (wins_server_subnet = make_subnet( "WINS_SERVER_SUBNET",
00303 WINS_SERVER_SUBNET,
00304 ipzero, ipzero, ipzero )) == NULL )
00305 return False;
00306 }
00307
00308 return True;
00309 }
00310
00311
00312
00313
00314
00315 BOOL we_are_a_wins_client(void)
00316 {
00317 if (wins_srv_count() > 0) {
00318 return True;
00319 }
00320
00321 return False;
00322 }
00323
00324
00325
00326
00327
00328 struct subnet_record *get_next_subnet_maybe_unicast(struct subnet_record *subrec)
00329 {
00330 if(subrec == unicast_subnet)
00331 return NULL;
00332 else if((subrec->next == NULL) && we_are_a_wins_client())
00333 return unicast_subnet;
00334 else
00335 return subrec->next;
00336 }
00337
00338
00339
00340
00341
00342
00343
00344
00345 struct subnet_record *get_next_subnet_maybe_unicast_or_wins_server(struct subnet_record *subrec)
00346 {
00347 if(subrec == unicast_subnet) {
00348 if(wins_server_subnet)
00349 return wins_server_subnet;
00350 else
00351 return NULL;
00352 }
00353
00354 if(wins_server_subnet && subrec == wins_server_subnet)
00355 return NULL;
00356
00357 if((subrec->next == NULL) && we_are_a_wins_client())
00358 return unicast_subnet;
00359 else
00360 return subrec->next;
00361 }