2 Unix SMB/Netbios implementation.
4 multiple interface handling
5 Copyright (C) Andrew Tridgell 1992-1997
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 extern int DEBUGLEVEL;
26 struct in_addr ipzero;
27 struct in_addr allones_ip;
28 struct in_addr loopback_ip;
29 static struct in_addr default_ip;
30 static struct in_addr default_bcast;
31 static struct in_addr default_nmask;
32 static BOOL got_ip=False;
33 static BOOL got_bcast=False;
34 static BOOL got_nmask=False;
36 static struct interface *local_interfaces = NULL;
38 struct interface *last_iface;
40 /****************************************************************************
41 calculate the default netmask for an address
42 ****************************************************************************/
43 static void default_netmask(struct in_addr *inm, struct in_addr *iad)
45 uint32 ad = ntohl(iad->s_addr);
48 ** Guess a netmask based on the class of the IP address given.
50 if ( (ad & 0x80000000) == 0 ) {
53 } else if ( (ad & 0xC0000000) == 0x80000000 ) {
56 } else if ( (ad & 0xE0000000) == 0xC0000000 ) {
60 /* class D or E; netmask doesn't make much sense - guess 4 bits */
63 inm->s_addr = htonl(nm);
67 /****************************************************************************
68 get the broadcast address for our address
69 (troyer@saifr00.ateng.az.honeywell.com)
70 ****************************************************************************/
71 static void get_broadcast(struct in_addr *if_ipaddr,
72 struct in_addr *if_bcast,
73 struct in_addr *if_nmask)
76 #ifndef NO_GET_BROADCAST
77 int sock = -1; /* AF_INET raw socket desc */
79 struct ifreq *ifr=NULL;
86 #elif defined(USE_IFREQ)
88 struct strioctl strioctl;
95 /* get a default netmask and broadcast */
96 default_netmask(if_nmask, if_ipaddr);
98 #ifndef NO_GET_BROADCAST
99 /* Create a socket to the INET kernel. */
101 if ((sock = socket(AF_INET, SOCK_RAW, PF_INET )) < 0)
103 if ((sock = socket(AF_INET, SOCK_DGRAM, 0 )) < 0)
106 DEBUG(0,( "Unable to open socket to get broadcast address\n"));
110 /* Get a list of the configured interfaces */
112 /* This is part of SCO Openserver 5: The ioctls are no longer part
113 if the lower level STREAMS interface glue. They are now real
116 if (ioctl(sock, SIOCGIFANUM, &n_interfaces) < 0) {
117 DEBUG(0,( "SIOCGIFANUM: %s\n", strerror(errno)));
119 DEBUG(0,( "number of interfaces returned is: %d\n", n_interfaces));
121 ifc.ifc_len = sizeof(struct ifreq) * n_interfaces;
122 ifc.ifc_buf = (caddr_t) alloca(ifc.ifc_len);
124 if (ioctl(sock, SIOCGIFCONF, &ifc) < 0)
125 DEBUG(0, ( "SIOCGIFCONF: %s\n", strerror(errno)));
129 for (i = 0; i < n_interfaces; ++i) {
130 if (if_ipaddr->s_addr ==
131 ((struct sockaddr_in *) &ifr[i].ifr_addr)->sin_addr.s_addr) {
138 #elif defined(USE_IFREQ)
139 ifc = (struct ifconf *)buff;
140 ifc->ifc_len = BUFSIZ - sizeof(struct ifconf);
141 strioctl.ic_cmd = SIOCGIFCONF;
142 strioctl.ic_dp = (char *)ifc;
143 strioctl.ic_len = sizeof(buff);
144 if (ioctl(sock, I_STR, &strioctl) < 0) {
145 DEBUG(0,( "I_STR/SIOCGIFCONF: %s\n", strerror(errno)));
147 ifr = (struct ifreq *)ifc->ifc_req;
149 /* Loop through interfaces, looking for given IP address */
150 for (i = ifc->ifc_len / sizeof(struct ifreq); --i >= 0; ifr++) {
151 if (if_ipaddr->s_addr ==
152 (*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr.s_addr) {
158 #elif defined(__FreeBSD__) || defined(NETBSD) || defined(AMIGA) || defined(_AIX41)
159 ifc.ifc_len = sizeof(buff);
161 if (ioctl(sock, SIOCGIFCONF, &ifc) < 0) {
162 DEBUG(0,("SIOCGIFCONF: %s\n", strerror(errno)));
165 /* Loop through interfaces, looking for given IP address */
168 if (if_ipaddr->s_addr ==
169 (*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr.s_addr) {
173 i -= ifr->ifr_addr.sa_len + IFNAMSIZ;
174 ifr = (struct ifreq*) ((char*) ifr + ifr->ifr_addr.sa_len + IFNAMSIZ);
178 ifc.ifc_len = sizeof(buff);
180 if (ioctl(sock, SIOCGIFCONF, &ifc) < 0) {
181 DEBUG(0,("SIOCGIFCONF: %s\n", strerror(errno)));
185 /* Loop through interfaces, looking for given IP address */
186 for (i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++) {
188 if (ioctl(sock, SIOCGIFADDR, ifr) < 0) break;
190 if (if_ipaddr->s_addr ==
191 (*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr.s_addr) {
200 DEBUG(0,("No interface found for address %s\n", inet_ntoa(*if_ipaddr)));
202 /* Get the netmask address from the kernel */
206 strioctl.ic_cmd = SIOCGIFNETMASK;
207 strioctl.ic_dp = (char *)&ifreq;
208 strioctl.ic_len = sizeof(struct ifreq);
209 if (ioctl(sock, I_STR, &strioctl) < 0)
210 DEBUG(0,("Failed I_STR/SIOCGIFNETMASK: %s\n", strerror(errno)));
212 *if_nmask = ((struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr;
214 if (ioctl(sock, SIOCGIFNETMASK, ifr) < 0)
215 DEBUG(0,("SIOCGIFNETMASK failed\n"));
217 *if_nmask = ((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr;
220 DEBUG(4,("Netmask for %s = %s\n", ifr->ifr_name,
221 inet_ntoa(*if_nmask)));
229 /* sanity check on the netmask */
231 uint32 nm = ntohl(if_nmask->s_addr);
232 if ((nm >> 24) != 0xFF) {
233 DEBUG(0,("Impossible netmask %s - using defaults\n",inet_ntoa(*if_nmask)));
234 default_netmask(if_nmask, if_ipaddr);
238 /* derive the broadcast assuming a 1's broadcast, as this is what
239 all MS operating systems do, we have to comply even if the unix
240 box is setup differently */
242 uint32 ad = ntohl(if_ipaddr->s_addr);
243 uint32 nm = ntohl(if_nmask->s_addr);
244 uint32 bc = (ad & nm) | (0xffffffff & ~nm);
245 if_bcast->s_addr = htonl(bc);
248 DEBUG(4,("Derived broadcast address %s\n", inet_ntoa(*if_bcast)));
249 } /* get_broadcast */
253 /****************************************************************************
254 load a list of network interfaces
255 ****************************************************************************/
256 static void interpret_interfaces(char *s, struct interface **interfaces,
261 struct interface *iface;
264 ipzero = *interpret_addr2("0.0.0.0");
265 allones_ip = *interpret_addr2("255.255.255.255");
266 loopback_ip = *interpret_addr2("127.0.0.1");
268 while (next_token(&ptr,token,NULL)) {
269 /* parse it into an IP address/netmasklength pair */
270 char *p = strchr(token,'/');
273 ip = *interpret_addr2(token);
275 /* maybe we already have it listed */
278 for (i=(*interfaces);i;i=i->next)
279 if (ip_equal(ip,i->ip)) break;
283 iface = (struct interface *)malloc(sizeof(*iface));
290 iface->nmask = *interpret_addr2(p+1);
292 iface->nmask.s_addr = htonl(~((1<<(32-atoi(p+1)))-1));
294 default_netmask(&iface->nmask,&iface->ip);
296 iface->bcast.s_addr = iface->ip.s_addr | ~iface->nmask.s_addr;
299 if (!(*interfaces)) {
300 (*interfaces) = iface;
302 last_iface->next = iface;
305 DEBUG(2,("Added %s ip=%s ",description,inet_ntoa(iface->ip)));
306 DEBUG(2,("bcast=%s ",inet_ntoa(iface->bcast)));
307 DEBUG(2,("nmask=%s\n",inet_ntoa(iface->nmask)));
310 if (*interfaces) return;
312 /* setup a default interface */
313 iface = (struct interface *)malloc(sizeof(*iface));
319 iface->ip = default_ip;
321 get_myname(NULL,&iface->ip);
325 iface->bcast = default_bcast;
327 get_broadcast(&iface->ip,&iface->bcast,&iface->nmask);
331 iface->nmask = default_nmask;
332 iface->bcast.s_addr = iface->ip.s_addr | ~iface->nmask.s_addr;
335 if (iface->bcast.s_addr != (iface->ip.s_addr | ~iface->nmask.s_addr)) {
336 DEBUG(2,("Warning: inconsistant interface %s\n",inet_ntoa(iface->ip)));
340 (*interfaces) = last_iface = iface;
342 DEBUG(2,("Added interface ip=%s ",inet_ntoa(iface->ip)));
343 DEBUG(2,("bcast=%s ",inet_ntoa(iface->bcast)));
344 DEBUG(2,("nmask=%s\n",inet_ntoa(iface->nmask)));
348 /****************************************************************************
349 load the remote and local interfaces
350 ****************************************************************************/
351 void load_interfaces(void)
353 /* add the machine's interfaces to local interface structure*/
354 interpret_interfaces(lp_interfaces(), &local_interfaces,"interface");
358 /****************************************************************************
359 override the defaults
360 **************************************************************************/
361 void iface_set_default(char *ip,char *bcast,char *nmask)
365 default_ip = *interpret_addr2(ip);
370 default_bcast = *interpret_addr2(bcast);
375 default_nmask = *interpret_addr2(nmask);
380 /****************************************************************************
381 check if an IP is one of mine
382 **************************************************************************/
383 BOOL ismyip(struct in_addr ip)
386 for (i=local_interfaces;i;i=i->next)
387 if (ip_equal(i->ip,ip)) return True;
391 /****************************************************************************
392 check if a bcast is one of mine
393 **************************************************************************/
394 BOOL ismybcast(struct in_addr bcast)
397 for (i=local_interfaces;i;i=i->next)
398 if (ip_equal(i->bcast,bcast)) return True;
402 /****************************************************************************
403 check if a packet is from a local (known) net
404 **************************************************************************/
405 BOOL is_local_net(struct in_addr from)
408 for (i=local_interfaces;i;i=i->next)
409 if((from.s_addr & i->nmask.s_addr) == (i->ip.s_addr & i->nmask.s_addr))
414 /****************************************************************************
415 how many interfaces do we have
416 **************************************************************************/
417 int iface_count(void)
422 for (i=local_interfaces;i;i=i->next)
427 /****************************************************************************
428 True if we have two or more interfaces.
429 **************************************************************************/
430 BOOL we_are_multihomed()
432 static int multi = -1;
435 multi = (iface_count() > 1 ? True : False);
440 /****************************************************************************
441 return the Nth interface
442 **************************************************************************/
443 struct interface *get_interface(int n)
447 for (i=local_interfaces;i && n;i=i->next)
454 /****************************************************************************
455 return IP of the Nth interface
456 **************************************************************************/
457 struct in_addr *iface_n_ip(int n)
461 for (i=local_interfaces;i && n;i=i->next)
464 if (i) return &i->ip;
468 /****************************************************************************
469 Try and find an interface that matches an ip. If we cannot, return NULL
470 **************************************************************************/
471 static struct interface *iface_find(struct in_addr ip)
474 if (zero_ip(ip)) return local_interfaces;
476 for (i=local_interfaces;i;i=i->next)
477 if (same_net(i->ip,ip,i->nmask)) return i;
482 /* these 3 functions return the ip/bcast/nmask for the interface
483 most appropriate for the given ip address. If they can't find
484 an appropriate interface they return the requested field of the
485 first known interface. */
487 struct in_addr *iface_bcast(struct in_addr ip)
489 struct interface *i = iface_find(ip);
490 return(i ? &i->bcast : &local_interfaces->bcast);
493 struct in_addr *iface_nmask(struct in_addr ip)
495 struct interface *i = iface_find(ip);
496 return(i ? &i->nmask : &local_interfaces->nmask);
499 struct in_addr *iface_ip(struct in_addr ip)
501 struct interface *i = iface_find(ip);
502 return(i ? &i->ip : &local_interfaces->ip);