This is *not* a big change (although it looks like one).
[samba.git] / source3 / lib / interface.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    multiple interface handling
5    Copyright (C) Andrew Tridgell 1992-1998
6    
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.
11    
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.
16    
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.
20 */
21
22 #include "includes.h"
23
24 extern int DEBUGLEVEL;
25
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;
35
36 static struct interface *local_interfaces  = NULL;
37
38 struct interface *last_iface;
39
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)
46 {
47         /*
48         ** Guess a netmask based on the class of the IP address given.
49         */
50         switch((ntohl(iad->s_addr) & 0xE0000000)) {
51         case 0x00000000:     /* Class A addr */
52         case 0x20000000:
53         case 0x40000000:
54         case 0x60000000:
55                 inm->s_addr = htonl(0xFF000000);
56                 break;
57                 
58         case 0x80000000:        /* Class B addr */
59         case 0xA0000000:
60                 inm->s_addr = htonl(0xFFFF0000);
61                 break;
62                 
63         case 0xC0000000:        /* Class C addr */
64                 inm->s_addr = htonl(0xFFFFFF00);
65                 break;
66                 
67         default:                /* ??? */
68                 inm->s_addr = htonl(0xFFFFFFF0);
69         }
70 }
71
72
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)
80 {  
81   BOOL found = False;
82 #ifndef NO_GET_BROADCAST
83   int sock = -1;               /* AF_INET raw socket desc */
84   char buff[1024];
85   struct ifreq *ifr=NULL;
86   int i;
87
88 #if defined(EVEREST)
89   int n_interfaces;
90   struct ifconf ifc;
91   struct ifreq  *ifreqs;
92 #elif defined(USE_IFREQ)
93   struct ifreq ifreq;
94   struct strioctl strioctl;
95   struct ifconf *ifc;
96 #else
97   struct ifconf ifc;
98 #endif
99 #endif
100
101   /* get a default netmask and broadcast */
102   default_netmask(if_nmask, if_ipaddr);
103
104 #ifndef NO_GET_BROADCAST  
105   /* Create a socket to the INET kernel. */
106 #if USE_SOCKRAW
107   if ((sock = socket(AF_INET, SOCK_RAW, PF_INET )) < 0)
108 #else
109     if ((sock = socket(AF_INET, SOCK_DGRAM, 0 )) < 0)
110 #endif
111       {
112         DEBUG(0,( "Unable to open socket to get broadcast address\n"));
113         return;
114       }
115   
116   /* Get a list of the configured interfaces */
117 #ifdef EVEREST
118   /* This is part of SCO Openserver 5: The ioctls are no longer part
119      if the lower level STREAMS interface glue. They are now real
120      ioctl calls */
121
122   if (ioctl(sock, SIOCGIFANUM, &n_interfaces) < 0) {
123     DEBUG(0,( "SIOCGIFANUM: %s\n", strerror(errno)));
124   } else {
125     DEBUG(0,( "number of interfaces returned is: %d\n", n_interfaces));
126
127     ifc.ifc_len = sizeof(struct ifreq) * n_interfaces;
128     ifc.ifc_buf = (caddr_t) alloca(ifc.ifc_len);
129
130     if (ioctl(sock, SIOCGIFCONF, &ifc) < 0)
131       DEBUG(0, ( "SIOCGIFCONF: %s\n", strerror(errno)));
132     else {
133       ifr = ifc.ifc_req;
134
135       for (i = 0; i < n_interfaces; ++i) {
136         if (if_ipaddr->s_addr ==
137             ((struct sockaddr_in *) &ifr[i].ifr_addr)->sin_addr.s_addr) {
138           found = True;
139           break;
140         }
141       }
142     }
143   }
144 #elif defined(USE_IFREQ)
145   ifc = (struct ifconf *)buff;
146   ifc->ifc_len = BUFSIZ - sizeof(struct ifconf);
147   strioctl.ic_cmd = SIOCGIFCONF;
148   strioctl.ic_dp  = (char *)ifc;
149   strioctl.ic_len = sizeof(buff);
150   if (ioctl(sock, I_STR, &strioctl) < 0) {
151     DEBUG(0,( "I_STR/SIOCGIFCONF: %s\n", strerror(errno)));
152   } else {
153     ifr = (struct ifreq *)ifc->ifc_req;  
154
155     /* Loop through interfaces, looking for given IP address */
156     for (i = ifc->ifc_len / sizeof(struct ifreq); --i >= 0; ifr++) {
157       if (if_ipaddr->s_addr ==
158           (*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr.s_addr) {
159         found = True;
160         break;
161       }
162     }
163   }
164 #elif defined(__FreeBSD__) || defined(NETBSD) || defined(AMIGA) || defined(_AIX41) || defined(__OpenBSD__)
165   ifc.ifc_len = sizeof(buff);
166   ifc.ifc_buf = buff;
167   if (ioctl(sock, SIOCGIFCONF, &ifc) < 0) {
168     DEBUG(0,("SIOCGIFCONF: %s\n", strerror(errno)));
169   } else {
170     ifr = ifc.ifc_req;
171     /* Loop through interfaces, looking for given IP address */
172     i = ifc.ifc_len;
173     while (i > 0) {
174       if (if_ipaddr->s_addr ==
175           (*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr.s_addr) {
176         found = True;
177         break;
178       }
179       i -= ifr->ifr_addr.sa_len + IFNAMSIZ;
180       ifr = (struct ifreq*) ((char*) ifr + ifr->ifr_addr.sa_len + IFNAMSIZ);
181     }
182   }
183 #else
184   ifc.ifc_len = sizeof(buff);
185   ifc.ifc_buf = buff;
186   if (ioctl(sock, SIOCGIFCONF, &ifc) < 0) {
187     DEBUG(0,("SIOCGIFCONF: %s\n", strerror(errno)));
188   } else {
189     ifr = ifc.ifc_req;
190   
191     /* Loop through interfaces, looking for given IP address */
192     for (i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++) {
193 #ifdef BSDI
194       if (ioctl(sock, SIOCGIFADDR, ifr) < 0) break;
195 #endif
196       if (if_ipaddr->s_addr ==
197           (*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr.s_addr) {
198         found = True;
199         break;
200       }
201     }
202   }
203 #endif
204   
205   if (!found) {
206     DEBUG(0,("No interface found for address %s\n", inet_ntoa(*if_ipaddr)));
207   } else {
208     /* Get the netmask address from the kernel */
209 #ifdef USE_IFREQ
210     ifreq = *ifr;
211   
212     strioctl.ic_cmd = SIOCGIFNETMASK;
213     strioctl.ic_dp  = (char *)&ifreq;
214     strioctl.ic_len = sizeof(struct ifreq);
215     if (ioctl(sock, I_STR, &strioctl) < 0)
216       DEBUG(0,("Failed I_STR/SIOCGIFNETMASK: %s\n", strerror(errno)));
217     else
218       *if_nmask = ((struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr;
219 #else
220     if (ioctl(sock, SIOCGIFNETMASK, ifr) < 0)
221       DEBUG(0,("SIOCGIFNETMASK failed\n"));
222     else
223       *if_nmask = ((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr;
224 #endif
225
226     DEBUG(4,("Netmask for %s = %s\n", ifr->ifr_name,
227              inet_ntoa(*if_nmask)));
228   }
229
230   /* Close up shop */
231   (void) close(sock);
232   
233 #endif
234
235   /* sanity check on the netmask */
236   {
237     uint32 nm;
238     short onbc;
239     short offbc;
240
241     nm = ntohl(if_nmask->s_addr);
242     onbc = 0;
243     offbc = 0;
244     while( (onbc + offbc) < 32 )
245          {
246            if( nm & 0x80000000 )
247              {
248                onbc++;
249                if( offbc ) /* already found an off bit, so mask is wrong */
250                  {
251                    onbc = 34;
252                  }
253              }
254            else
255              {
256                offbc++;
257              }
258            nm <<= 1;
259          }
260     if ((onbc < 8)||(onbc == 34)) {
261       DEBUG(0,("Impossible netmask %s - using defaults\n",inet_ntoa(*if_nmask)));
262       default_netmask(if_nmask, if_ipaddr);      
263     }
264   }
265
266   /* derive the broadcast assuming a 1's broadcast, as this is what
267      all MS operating systems do, we have to comply even if the unix
268      box is setup differently */
269   {
270     if_bcast->s_addr = MKBCADDR(if_ipaddr->s_addr, if_nmask->s_addr);
271   }
272   
273   DEBUG(4,("Derived broadcast address %s\n", inet_ntoa(*if_bcast)));
274 }  /* get_broadcast */
275
276
277
278 /****************************************************************************
279 load a list of network interfaces
280 ****************************************************************************/
281 static void interpret_interfaces(char *s, struct interface **interfaces,
282                 char *description)
283 {
284   char *ptr;
285   fstring token;
286   struct interface *iface;
287   struct in_addr ip;
288
289   ptr = s;
290   ipzero = *interpret_addr2("0.0.0.0");
291   allones_ip = *interpret_addr2("255.255.255.255");
292   loopback_ip = *interpret_addr2("127.0.0.1");
293
294   while (next_token(&ptr,token,NULL)) {
295     /* parse it into an IP address/netmasklength pair */
296     char *p = strchr(token,'/');
297     if (p) *p++ = 0;
298
299     ip = *interpret_addr2(token);
300
301     /* maybe we already have it listed */
302     {
303       struct interface *i;
304       for (i=(*interfaces);i;i=i->next)
305         if (ip_equal(ip,i->ip)) break;
306       if (i) continue;
307     }
308
309     iface = (struct interface *)malloc(sizeof(*iface));
310     if (!iface) return;
311
312     iface->ip = ip;
313
314     if (p) {
315       if (strlen(p) > 2)
316        iface->nmask = *interpret_addr2(p);
317       else
318        iface->nmask.s_addr = htonl(((ALLONES >> atoi(p)) ^ ALLONES));
319     } else {
320       default_netmask(&iface->nmask,&iface->ip);
321     }
322     iface->bcast.s_addr = MKBCADDR(iface->ip.s_addr, iface->nmask.s_addr);
323     iface->next = NULL;
324
325     if (!(*interfaces)) {
326       (*interfaces) = iface;
327     } else {
328       last_iface->next = iface;
329     }
330     last_iface = iface;
331     DEBUG(2,("Added %s ip=%s ",description,inet_ntoa(iface->ip)));
332     DEBUG(2,("bcast=%s ",inet_ntoa(iface->bcast)));
333     DEBUG(2,("nmask=%s\n",inet_ntoa(iface->nmask)));         
334   }
335
336   if (*interfaces) return;
337
338   /* setup a default interface */
339   iface = (struct interface *)malloc(sizeof(*iface));
340   if (!iface) return;
341
342   iface->next = NULL;
343
344   if (got_ip) {
345     iface->ip = default_ip;
346   } else {
347     get_myname(NULL,&iface->ip);
348   }
349
350   if (got_bcast) {
351     iface->bcast = default_bcast;
352   } else {
353     get_broadcast(&iface->ip,&iface->bcast,&iface->nmask);
354   }
355
356   if (got_nmask) {
357     iface->nmask = default_nmask;
358     iface->bcast.s_addr = MKBCADDR(iface->ip.s_addr, iface->nmask.s_addr);
359   }
360
361   if (iface->bcast.s_addr != MKBCADDR(iface->ip.s_addr, iface->nmask.s_addr)) {
362     DEBUG(2,("Warning: inconsistant interface %s\n",inet_ntoa(iface->ip)));
363   }
364
365   iface->next = NULL;
366   (*interfaces) = last_iface = iface;
367
368   DEBUG(2,("Added interface ip=%s ",inet_ntoa(iface->ip)));
369   DEBUG(2,("bcast=%s ",inet_ntoa(iface->bcast)));
370   DEBUG(2,("nmask=%s\n",inet_ntoa(iface->nmask)));           
371 }
372
373
374 /****************************************************************************
375 load the remote and local interfaces
376 ****************************************************************************/
377 void load_interfaces(void)
378 {
379   /* add the machine's interfaces to local interface structure*/
380   interpret_interfaces(lp_interfaces(), &local_interfaces,"interface");
381 }
382
383
384 /****************************************************************************
385   override the defaults
386   **************************************************************************/
387 void iface_set_default(char *ip,char *bcast,char *nmask)
388 {
389   if (ip) {
390     got_ip = True;
391     default_ip = *interpret_addr2(ip);
392   }
393
394   if (bcast) {
395     got_bcast = True;
396     default_bcast = *interpret_addr2(bcast);
397   }
398
399   if (nmask) {
400     got_nmask = True;
401     default_nmask = *interpret_addr2(nmask);
402   }
403 }
404
405
406 /****************************************************************************
407   check if an IP is one of mine
408   **************************************************************************/
409 BOOL ismyip(struct in_addr ip)
410 {
411   struct interface *i;
412   for (i=local_interfaces;i;i=i->next)
413     if (ip_equal(i->ip,ip)) return True;
414   return False;
415 }
416
417 /****************************************************************************
418   check if a bcast is one of mine
419   **************************************************************************/
420 BOOL ismybcast(struct in_addr bcast)
421 {
422   struct interface *i;
423   for (i=local_interfaces;i;i=i->next)
424     if (ip_equal(i->bcast,bcast)) return True;
425   return False;
426 }
427
428 /****************************************************************************
429   check if a packet is from a local (known) net
430   **************************************************************************/
431 BOOL is_local_net(struct in_addr from)
432 {
433   struct interface *i;
434   for (i=local_interfaces;i;i=i->next)
435     if((from.s_addr & i->nmask.s_addr) == (i->ip.s_addr & i->nmask.s_addr))
436       return True;
437   return False;
438 }
439
440 /****************************************************************************
441   how many interfaces do we have
442   **************************************************************************/
443 int iface_count(void)
444 {
445   int ret = 0;
446   struct interface *i;
447
448   for (i=local_interfaces;i;i=i->next)
449     ret++;
450   return ret;
451 }
452
453 /****************************************************************************
454  True if we have two or more interfaces.
455   **************************************************************************/
456 BOOL we_are_multihomed()
457 {
458   static int multi = -1;
459
460   if(multi == -1)
461     multi = (iface_count() > 1 ? True : False);
462
463   return multi;
464 }
465
466 /****************************************************************************
467   return the Nth interface
468   **************************************************************************/
469 struct interface *get_interface(int n)
470
471   struct interface *i;
472   
473   for (i=local_interfaces;i && n;i=i->next)
474     n--;
475
476   if (i) return i;
477   return NULL;
478 }
479
480 /****************************************************************************
481   return IP of the Nth interface
482   **************************************************************************/
483 struct in_addr *iface_n_ip(int n)
484 {
485   struct interface *i;
486   
487   for (i=local_interfaces;i && n;i=i->next)
488     n--;
489
490   if (i) return &i->ip;
491   return NULL;
492 }
493
494 /****************************************************************************
495 Try and find an interface that matches an ip. If we cannot, return NULL
496   **************************************************************************/
497 static struct interface *iface_find(struct in_addr ip)
498 {
499   struct interface *i;
500   if (zero_ip(ip)) return local_interfaces;
501
502   for (i=local_interfaces;i;i=i->next)
503     if (same_net(i->ip,ip,i->nmask)) return i;
504
505   return NULL;
506 }
507
508 /* these 3 functions return the ip/bcast/nmask for the interface
509    most appropriate for the given ip address. If they can't find
510    an appropriate interface they return the requested field of the
511    first known interface. */
512
513 struct in_addr *iface_bcast(struct in_addr ip)
514 {
515   struct interface *i = iface_find(ip);
516   return(i ? &i->bcast : &local_interfaces->bcast);
517 }
518
519 struct in_addr *iface_nmask(struct in_addr ip)
520 {
521   struct interface *i = iface_find(ip);
522   return(i ? &i->nmask : &local_interfaces->nmask);
523 }
524
525 struct in_addr *iface_ip(struct in_addr ip)
526 {
527   struct interface *i = iface_find(ip);
528   return(i ? &i->ip : &local_interfaces->ip);
529 }
530
531
532