00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "includes.h"
00022
00023 static struct iface_struct *probed_ifaces;
00024 static int total_probed;
00025
00026 struct in_addr allones_ip;
00027 struct in_addr loopback_ip;
00028
00029 static struct interface *local_interfaces;
00030
00031 #define ALLONES ((uint32)0xFFFFFFFF)
00032 #define MKBCADDR(_IP, _NM) ((_IP & _NM) | (_NM ^ ALLONES))
00033 #define MKNETADDR(_IP, _NM) (_IP & _NM)
00034
00035
00036
00037
00038 static struct interface *iface_find(struct in_addr ip, BOOL CheckMask)
00039 {
00040 struct interface *i;
00041 if (is_zero_ip(ip)) return local_interfaces;
00042
00043 for (i=local_interfaces;i;i=i->next)
00044 if (CheckMask) {
00045 if (same_net(i->ip,ip,i->nmask)) return i;
00046 } else if ((i->ip).s_addr == ip.s_addr) return i;
00047
00048 return NULL;
00049 }
00050
00051
00052
00053
00054
00055 static void add_interface(struct in_addr ip, struct in_addr nmask)
00056 {
00057 struct interface *iface;
00058 if (iface_find(ip, False)) {
00059 DEBUG(3,("not adding duplicate interface %s\n",inet_ntoa(ip)));
00060 return;
00061 }
00062
00063 #if !defined(__s390__)
00064 if (ip_equal(nmask, allones_ip)) {
00065 DEBUG(3,("not adding non-broadcast interface %s\n",inet_ntoa(ip)));
00066 return;
00067 }
00068 #endif
00069
00070 iface = SMB_MALLOC_P(struct interface);
00071 if (!iface) return;
00072
00073 ZERO_STRUCTPN(iface);
00074
00075 iface->ip = ip;
00076 iface->nmask = nmask;
00077 iface->bcast.s_addr = MKBCADDR(iface->ip.s_addr, iface->nmask.s_addr);
00078
00079 DLIST_ADD(local_interfaces, iface);
00080
00081 DEBUG(2,("added interface ip=%s ",inet_ntoa(iface->ip)));
00082 DEBUG(2,("bcast=%s ",inet_ntoa(iface->bcast)));
00083 DEBUG(2,("nmask=%s\n",inet_ntoa(iface->nmask)));
00084 }
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099 static void interpret_interface(char *token)
00100 {
00101 struct in_addr ip, nmask;
00102 char *p;
00103 int i, added=0;
00104
00105 zero_ip(&ip);
00106 zero_ip(&nmask);
00107
00108
00109 for (i=0;i<total_probed;i++) {
00110 if (gen_fnmatch(token, probed_ifaces[i].name) == 0) {
00111 add_interface(probed_ifaces[i].ip,
00112 probed_ifaces[i].netmask);
00113 added = 1;
00114 }
00115 }
00116 if (added) return;
00117
00118
00119 p = strchr_m(token,'/');
00120 if (!p) {
00121 ip = *interpret_addr2(token);
00122 for (i=0;i<total_probed;i++) {
00123 if (ip.s_addr == probed_ifaces[i].ip.s_addr &&
00124 !ip_equal(allones_ip, probed_ifaces[i].netmask)) {
00125 add_interface(probed_ifaces[i].ip,
00126 probed_ifaces[i].netmask);
00127 return;
00128 }
00129 }
00130 DEBUG(2,("can't determine netmask for %s\n", token));
00131 return;
00132 }
00133
00134
00135 *p = 0;
00136 ip = *interpret_addr2(token);
00137 *p++ = '/';
00138
00139 if (strlen(p) > 2) {
00140 nmask = *interpret_addr2(p);
00141 } else {
00142 nmask.s_addr = htonl(((ALLONES >> atoi(p)) ^ ALLONES));
00143 }
00144
00145
00146 if (ip.s_addr == MKBCADDR(ip.s_addr, nmask.s_addr) ||
00147 ip.s_addr == MKNETADDR(ip.s_addr, nmask.s_addr)) {
00148 for (i=0;i<total_probed;i++) {
00149 if (same_net(ip, probed_ifaces[i].ip, nmask)) {
00150 add_interface(probed_ifaces[i].ip, nmask);
00151 return;
00152 }
00153 }
00154 DEBUG(2,("Can't determine ip for broadcast address %s\n", token));
00155 return;
00156 }
00157
00158 add_interface(ip, nmask);
00159 }
00160
00161
00162
00163
00164
00165 void load_interfaces(void)
00166 {
00167 const char **ptr;
00168 int i;
00169 struct iface_struct ifaces[MAX_INTERFACES];
00170
00171 ptr = lp_interfaces();
00172
00173 allones_ip = *interpret_addr2("255.255.255.255");
00174 loopback_ip = *interpret_addr2("127.0.0.1");
00175
00176 SAFE_FREE(probed_ifaces);
00177
00178
00179 while (local_interfaces) {
00180 struct interface *iface = local_interfaces;
00181 DLIST_REMOVE(local_interfaces, local_interfaces);
00182 ZERO_STRUCTPN(iface);
00183 SAFE_FREE(iface);
00184 }
00185
00186
00187 total_probed = get_interfaces(ifaces, MAX_INTERFACES);
00188
00189 if (total_probed > 0) {
00190 probed_ifaces = (struct iface_struct *)memdup(ifaces, sizeof(ifaces[0])*total_probed);
00191 if (!probed_ifaces) {
00192 DEBUG(0,("ERROR: memdup failed\n"));
00193 exit(1);
00194 }
00195 }
00196
00197
00198
00199 if (!ptr || !*ptr || !**ptr) {
00200 if (total_probed <= 0) {
00201 DEBUG(0,("ERROR: Could not determine network interfaces, you must use a interfaces config line\n"));
00202 exit(1);
00203 }
00204 for (i=0;i<total_probed;i++) {
00205 if (
00206 #if !defined(__s390__)
00207 probed_ifaces[i].netmask.s_addr != allones_ip.s_addr &&
00208 #endif
00209 probed_ifaces[i].ip.s_addr != loopback_ip.s_addr) {
00210 add_interface(probed_ifaces[i].ip,
00211 probed_ifaces[i].netmask);
00212 }
00213 }
00214 return;
00215 }
00216
00217 if (ptr) {
00218 while (*ptr) {
00219 char *ptr_cpy = SMB_STRDUP(*ptr);
00220 if (ptr_cpy) {
00221 interpret_interface(ptr_cpy);
00222 free(ptr_cpy);
00223 }
00224 ptr++;
00225 }
00226 }
00227
00228 if (!local_interfaces) {
00229 DEBUG(0,("WARNING: no network interfaces found\n"));
00230 }
00231 }
00232
00233
00234 void gfree_interfaces(void)
00235 {
00236 while (local_interfaces) {
00237 struct interface *iface = local_interfaces;
00238 DLIST_REMOVE(local_interfaces, local_interfaces);
00239 ZERO_STRUCTPN(iface);
00240 SAFE_FREE(iface);
00241 }
00242
00243 SAFE_FREE(probed_ifaces);
00244 }
00245
00246
00247
00248
00249 BOOL interfaces_changed(void)
00250 {
00251 int n;
00252 struct iface_struct ifaces[MAX_INTERFACES];
00253
00254 n = get_interfaces(ifaces, MAX_INTERFACES);
00255
00256 if ((n > 0 )&& (n != total_probed ||
00257 memcmp(ifaces, probed_ifaces, sizeof(ifaces[0])*n))) {
00258 return True;
00259 }
00260
00261 return False;
00262 }
00263
00264
00265
00266
00267
00268 BOOL ismyip(struct in_addr ip)
00269 {
00270 struct interface *i;
00271 for (i=local_interfaces;i;i=i->next)
00272 if (ip_equal(i->ip,ip)) return True;
00273 return False;
00274 }
00275
00276
00277
00278
00279 BOOL is_local_net(struct in_addr from)
00280 {
00281 struct interface *i;
00282 for (i=local_interfaces;i;i=i->next) {
00283 if((from.s_addr & i->nmask.s_addr) ==
00284 (i->ip.s_addr & i->nmask.s_addr))
00285 return True;
00286 }
00287 return False;
00288 }
00289
00290
00291
00292
00293 int iface_count(void)
00294 {
00295 int ret = 0;
00296 struct interface *i;
00297
00298 for (i=local_interfaces;i;i=i->next)
00299 ret++;
00300 return ret;
00301 }
00302
00303
00304
00305
00306 int iface_count_nl(void)
00307 {
00308 int ret = 0;
00309 struct interface *i;
00310
00311 for (i=local_interfaces;i;i=i->next) {
00312 if (ip_equal(i->ip, loopback_ip)) {
00313 continue;
00314 }
00315 ret++;
00316 }
00317 return ret;
00318 }
00319
00320
00321
00322
00323 struct interface *get_interface(int n)
00324 {
00325 struct interface *i;
00326
00327 for (i=local_interfaces;i && n;i=i->next)
00328 n--;
00329
00330 if (i) return i;
00331 return NULL;
00332 }
00333
00334
00335
00336
00337 struct in_addr *iface_n_ip(int n)
00338 {
00339 struct interface *i;
00340
00341 for (i=local_interfaces;i && n;i=i->next)
00342 n--;
00343
00344 if (i) return &i->ip;
00345 return NULL;
00346 }
00347
00348
00349
00350
00351 struct in_addr *iface_n_bcast(int n)
00352 {
00353 struct interface *i;
00354
00355 for (i=local_interfaces;i && n;i=i->next)
00356 n--;
00357
00358 if (i) return &i->bcast;
00359 return NULL;
00360 }
00361
00362
00363
00364
00365
00366
00367
00368 struct in_addr *iface_ip(struct in_addr ip)
00369 {
00370 struct interface *i = iface_find(ip, True);
00371 return(i ? &i->ip : &local_interfaces->ip);
00372 }
00373
00374
00375
00376
00377 BOOL iface_local(struct in_addr ip)
00378 {
00379 return iface_find(ip, True) ? True : False;
00380 }