00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "includes.h"
00024
00025 extern struct in_addr loopback_ip;
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063 #define DEATH_TIME 600
00064
00065
00066
00067
00068
00069
00070
00071 #define WINS_SRV_FMT "WINS_SRV_DEAD/%s,%s"
00072
00073 static char *wins_srv_keystr(struct in_addr wins_ip, struct in_addr src_ip)
00074 {
00075 char *keystr = NULL, *wins_ip_addr = NULL, *src_ip_addr = NULL;
00076
00077 wins_ip_addr = SMB_STRDUP(inet_ntoa(wins_ip));
00078 src_ip_addr = SMB_STRDUP(inet_ntoa(src_ip));
00079
00080 if ( !wins_ip_addr || !src_ip_addr ) {
00081 DEBUG(0,("wins_srv_keystr: malloc error\n"));
00082 goto done;
00083 }
00084
00085 if (asprintf(&keystr, WINS_SRV_FMT, wins_ip_addr, src_ip_addr) == -1) {
00086 DEBUG(0, (": ns_srv_keystr: malloc error for key string\n"));
00087 }
00088
00089 done:
00090 SAFE_FREE(wins_ip_addr);
00091 SAFE_FREE(src_ip_addr);
00092
00093 return keystr;
00094 }
00095
00096
00097
00098
00099
00100 BOOL wins_srv_is_dead(struct in_addr wins_ip, struct in_addr src_ip)
00101 {
00102 char *keystr = wins_srv_keystr(wins_ip, src_ip);
00103 BOOL result;
00104
00105
00106
00107 result = gencache_get(keystr, NULL, NULL);
00108 SAFE_FREE(keystr);
00109
00110 DEBUG(4, ("wins_srv_is_dead: %s is %s\n", inet_ntoa(wins_ip),
00111 result ? "dead" : "alive"));
00112
00113 return result;
00114 }
00115
00116
00117
00118
00119
00120 void wins_srv_alive(struct in_addr wins_ip, struct in_addr src_ip)
00121 {
00122 char *keystr = wins_srv_keystr(wins_ip, src_ip);
00123
00124 gencache_del(keystr);
00125 SAFE_FREE(keystr);
00126
00127 DEBUG(4, ("wins_srv_alive: marking wins server %s alive\n",
00128 inet_ntoa(wins_ip)));
00129 }
00130
00131
00132
00133
00134 void wins_srv_died(struct in_addr wins_ip, struct in_addr src_ip)
00135 {
00136 char *keystr;
00137
00138 if (is_zero_ip(wins_ip) || wins_srv_is_dead(wins_ip, src_ip))
00139 return;
00140
00141 keystr = wins_srv_keystr(wins_ip, src_ip);
00142
00143 gencache_set(keystr, "DOWN", time(NULL) + DEATH_TIME);
00144
00145 SAFE_FREE(keystr);
00146
00147 DEBUG(4,("Marking wins server %s dead for %u seconds from source %s\n",
00148 inet_ntoa(wins_ip), DEATH_TIME, inet_ntoa(src_ip)));
00149 }
00150
00151
00152
00153
00154 unsigned wins_srv_count(void)
00155 {
00156 const char **list;
00157 int count = 0;
00158
00159 if (lp_wins_support()) {
00160
00161 return 1;
00162 }
00163
00164 list = lp_wins_server_list();
00165 for (count=0; list && list[count]; count++)
00166 ;
00167
00168 return count;
00169 }
00170
00171
00172
00173 struct tagged_ip {
00174 fstring tag;
00175 struct in_addr ip;
00176 };
00177
00178
00179
00180
00181
00182
00183
00184 static void parse_ip(struct tagged_ip *ip, const char *str)
00185 {
00186 char *s = strchr(str, ':');
00187 if (!s) {
00188 fstrcpy(ip->tag, "*");
00189 ip->ip = *interpret_addr2(str);
00190 return;
00191 }
00192
00193 ip->ip = *interpret_addr2(s+1);
00194 fstrcpy(ip->tag, str);
00195 s = strchr(ip->tag, ':');
00196 if (s) *s = 0;
00197 }
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208 char **wins_srv_tags(void)
00209 {
00210 char **ret = NULL;
00211 int count=0, i, j;
00212 const char **list;
00213
00214 if (lp_wins_support()) {
00215
00216
00217 ret = SMB_MALLOC_ARRAY(char *, 2);
00218 if (!ret) return NULL;
00219 ret[0] = SMB_STRDUP("*");
00220 ret[1] = NULL;
00221 return ret;
00222 }
00223
00224 list = lp_wins_server_list();
00225 if (!list)
00226 return NULL;
00227
00228
00229 for (i=0;list[i];i++) {
00230 struct tagged_ip t_ip;
00231
00232 parse_ip(&t_ip, list[i]);
00233
00234
00235 for (j=0;j<count;j++) {
00236 if (strcmp(ret[j], t_ip.tag) == 0) {
00237 break;
00238 }
00239 }
00240
00241 if (j != count) {
00242
00243 continue;
00244 }
00245
00246
00247 ret = SMB_REALLOC_ARRAY(ret, char *, count+2);
00248 if (!ret) {
00249 return NULL;
00250 }
00251 ret[count] = SMB_STRDUP(t_ip.tag);
00252 if (!ret[count]) break;
00253 count++;
00254 }
00255
00256 if (count) {
00257
00258 ret[count] = NULL;
00259 }
00260
00261 return ret;
00262 }
00263
00264
00265 void wins_srv_tags_free(char **list)
00266 {
00267 int i;
00268 if (!list) return;
00269 for (i=0; list[i]; i++) {
00270 free(list[i]);
00271 }
00272 free(list);
00273 }
00274
00275
00276
00277
00278
00279
00280 struct in_addr wins_srv_ip_tag(const char *tag, struct in_addr src_ip)
00281 {
00282 const char **list;
00283 int i;
00284 struct tagged_ip t_ip;
00285
00286
00287 if (lp_wins_support()) {
00288 return loopback_ip;
00289 }
00290
00291 list = lp_wins_server_list();
00292 if (!list || !list[0]) {
00293 struct in_addr ip;
00294 zero_ip(&ip);
00295 return ip;
00296 }
00297
00298
00299 for (i=0; list[i]; i++) {
00300 parse_ip(&t_ip, list[i]);
00301 if (strcmp(tag, t_ip.tag) != 0) {
00302
00303 continue;
00304 }
00305 if (!wins_srv_is_dead(t_ip.ip, src_ip)) {
00306 fstring src_name;
00307 fstrcpy(src_name, inet_ntoa(src_ip));
00308 DEBUG(6,("Current wins server for tag '%s' with source %s is %s\n",
00309 tag,
00310 src_name,
00311 inet_ntoa(t_ip.ip)));
00312 return t_ip.ip;
00313 }
00314 }
00315
00316
00317 for (i=0; list[i]; i++) {
00318 parse_ip(&t_ip, list[i]);
00319 if (strcmp(tag, t_ip.tag) != 0) {
00320 continue;
00321 }
00322 return t_ip.ip;
00323 }
00324
00325
00326 zero_ip(&t_ip.ip);
00327 return t_ip.ip;
00328 }
00329
00330
00331
00332
00333
00334
00335 unsigned wins_srv_count_tag(const char *tag)
00336 {
00337 const char **list;
00338 int i, count=0;
00339
00340
00341 if (lp_wins_support()) {
00342 return 1;
00343 }
00344
00345 list = lp_wins_server_list();
00346 if (!list || !list[0]) {
00347 return 0;
00348 }
00349
00350
00351 for (i=0; list[i]; i++) {
00352 struct tagged_ip t_ip;
00353 parse_ip(&t_ip, list[i]);
00354 if (strcmp(tag, t_ip.tag) == 0) {
00355 count++;
00356 }
00357 }
00358
00359 return count;
00360 }