2 Unix SMB/Netbios implementation.
4 multiple interface handling
5 Copyright (C) Andrew Tridgell 1992-1998
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 #define ALLONES ((uint32)0xFFFFFFFF)
41 #define MKBCADDR(_IP, _NM) ((_IP & _NM) | (_NM ^ ALLONES))
42 /****************************************************************************
43 calculate the default netmask for an address
44 ****************************************************************************/
45 static void default_netmask(struct in_addr *inm, struct in_addr *iad)
48 ** Guess a netmask based on the class of the IP address given.
50 switch((ntohl(iad->s_addr) & 0xE0000000)) {
51 case 0x00000000: /* Class A addr */
55 inm->s_addr = htonl(0xFF000000);
58 case 0x80000000: /* Class B addr */
60 inm->s_addr = htonl(0xFFFF0000);
63 case 0xC0000000: /* Class C addr */
64 inm->s_addr = htonl(0xFFFFFF00);
68 inm->s_addr = htonl(0xFFFFFFF0);
73 /****************************************************************************
74 get the broadcast address for our address
75 (troyer@saifr00.ateng.az.honeywell.com)
76 ****************************************************************************/
77 static void get_broadcast(struct in_addr *if_ipaddr,
78 struct in_addr *if_bcast,
79 struct in_addr *if_nmask)
85 /* get a default netmask and broadcast */
86 default_netmask(if_nmask, if_ipaddr);
88 get_netmask(if_ipaddr, if_nmask);
90 /* sanity check on the netmask */
91 nm = ntohl(if_nmask->s_addr);
94 while((onbc + offbc) < 32) {
98 /* already found an off bit, so mask
107 if ((onbc < 8)||(onbc == 34)) {
108 DEBUG(0,("Impossible netmask %s - using defaults\n",
109 inet_ntoa(*if_nmask)));
110 default_netmask(if_nmask, if_ipaddr);
113 /* derive the broadcast assuming a 1's broadcast, as this is what
114 all MS operating systems do, we have to comply even if the unix
115 box is setup differently */
116 if_bcast->s_addr = MKBCADDR(if_ipaddr->s_addr, if_nmask->s_addr);
118 DEBUG(4,("Derived broadcast address %s\n", inet_ntoa(*if_bcast)));
123 /****************************************************************************
124 load a list of network interfaces
125 ****************************************************************************/
126 static void interpret_interfaces(char *s, struct interface **interfaces,
131 struct interface *iface;
135 ipzero = *interpret_addr2("0.0.0.0");
136 allones_ip = *interpret_addr2("255.255.255.255");
137 loopback_ip = *interpret_addr2("127.0.0.1");
139 while (next_token(&ptr,token,NULL)) {
140 /* parse it into an IP address/netmasklength pair */
141 char *p = strchr(token,'/');
144 ip = *interpret_addr2(token);
146 /* maybe we already have it listed */
149 for (i=(*interfaces);i;i=i->next)
150 if (ip_equal(ip,i->ip)) break;
154 iface = (struct interface *)malloc(sizeof(*iface));
161 iface->nmask = *interpret_addr2(p);
163 iface->nmask.s_addr = htonl(((ALLONES >> atoi(p)) ^ ALLONES));
165 default_netmask(&iface->nmask,&iface->ip);
167 iface->bcast.s_addr = MKBCADDR(iface->ip.s_addr, iface->nmask.s_addr);
170 if (!(*interfaces)) {
171 (*interfaces) = iface;
173 last_iface->next = iface;
176 DEBUG(2,("Added %s ip=%s ",description,inet_ntoa(iface->ip)));
177 DEBUG(2,("bcast=%s ",inet_ntoa(iface->bcast)));
178 DEBUG(2,("nmask=%s\n",inet_ntoa(iface->nmask)));
181 if (*interfaces) return;
183 /* setup a default interface */
184 iface = (struct interface *)malloc(sizeof(*iface));
190 iface->ip = default_ip;
192 get_myname(NULL,&iface->ip);
196 iface->bcast = default_bcast;
198 get_broadcast(&iface->ip,&iface->bcast,&iface->nmask);
202 iface->nmask = default_nmask;
203 iface->bcast.s_addr = MKBCADDR(iface->ip.s_addr, iface->nmask.s_addr);
206 if (iface->bcast.s_addr != MKBCADDR(iface->ip.s_addr, iface->nmask.s_addr)) {
207 DEBUG(2,("Warning: inconsistant interface %s\n",inet_ntoa(iface->ip)));
211 (*interfaces) = last_iface = iface;
213 DEBUG(2,("Added interface ip=%s ",inet_ntoa(iface->ip)));
214 DEBUG(2,("bcast=%s ",inet_ntoa(iface->bcast)));
215 DEBUG(2,("nmask=%s\n",inet_ntoa(iface->nmask)));
219 /****************************************************************************
220 load the remote and local interfaces
221 ****************************************************************************/
222 void load_interfaces(void)
224 /* add the machine's interfaces to local interface structure*/
225 interpret_interfaces(lp_interfaces(), &local_interfaces,"interface");
229 /****************************************************************************
230 override the defaults
231 **************************************************************************/
232 void iface_set_default(char *ip,char *bcast,char *nmask)
236 default_ip = *interpret_addr2(ip);
241 default_bcast = *interpret_addr2(bcast);
246 default_nmask = *interpret_addr2(nmask);
251 /****************************************************************************
252 check if an IP is one of mine
253 **************************************************************************/
254 BOOL ismyip(struct in_addr ip)
257 for (i=local_interfaces;i;i=i->next)
258 if (ip_equal(i->ip,ip)) return True;
262 /****************************************************************************
263 check if a bcast is one of mine
264 **************************************************************************/
265 BOOL ismybcast(struct in_addr bcast)
268 for (i=local_interfaces;i;i=i->next)
269 if (ip_equal(i->bcast,bcast)) return True;
273 /****************************************************************************
274 check if a packet is from a local (known) net
275 **************************************************************************/
276 BOOL is_local_net(struct in_addr from)
279 for (i=local_interfaces;i;i=i->next)
280 if((from.s_addr & i->nmask.s_addr) == (i->ip.s_addr & i->nmask.s_addr))
285 /****************************************************************************
286 how many interfaces do we have
287 **************************************************************************/
288 int iface_count(void)
293 for (i=local_interfaces;i;i=i->next)
298 /****************************************************************************
299 True if we have two or more interfaces.
300 **************************************************************************/
301 BOOL we_are_multihomed(void)
303 static int multi = -1;
306 multi = (iface_count() > 1 ? True : False);
311 /****************************************************************************
312 return the Nth interface
313 **************************************************************************/
314 struct interface *get_interface(int n)
318 for (i=local_interfaces;i && n;i=i->next)
325 /****************************************************************************
326 return IP of the Nth interface
327 **************************************************************************/
328 struct in_addr *iface_n_ip(int n)
332 for (i=local_interfaces;i && n;i=i->next)
335 if (i) return &i->ip;
339 /****************************************************************************
340 Try and find an interface that matches an ip. If we cannot, return NULL
341 **************************************************************************/
342 static struct interface *iface_find(struct in_addr ip)
345 if (zero_ip(ip)) return local_interfaces;
347 for (i=local_interfaces;i;i=i->next)
348 if (same_net(i->ip,ip,i->nmask)) return i;
353 /* these 3 functions return the ip/bcast/nmask for the interface
354 most appropriate for the given ip address. If they can't find
355 an appropriate interface they return the requested field of the
356 first known interface. */
358 struct in_addr *iface_bcast(struct in_addr ip)
360 struct interface *i = iface_find(ip);
361 return(i ? &i->bcast : &local_interfaces->bcast);
364 struct in_addr *iface_nmask(struct in_addr ip)
366 struct interface *i = iface_find(ip);
367 return(i ? &i->nmask : &local_interfaces->nmask);
370 struct in_addr *iface_ip(struct in_addr ip)
372 struct interface *i = iface_find(ip);
373 return(i ? &i->ip : &local_interfaces->ip);