ded70683e0ddcabdbde3c699dbd154d77bf82e9f
[obnox/samba/samba-obnox.git] / source / lib / interface.c
1 /*
2    Unix SMB/CIFS implementation.
3    multiple interface handling
4    Copyright (C) Andrew Tridgell 1992-1998
5    Copyright (C) Jeremy Allison 2007
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 3 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, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "includes.h"
22
23 static struct iface_struct *probed_ifaces;
24 static int total_probed;
25
26 static struct interface *local_interfaces;
27
28 /****************************************************************************
29  Check if an IP is one of mine.
30 **************************************************************************/
31
32 bool ismyaddr(const struct sockaddr_storage *ip)
33 {
34         struct interface *i;
35         for (i=local_interfaces;i;i=i->next) {
36                 if (addr_equal(&i->ip,ip)) {
37                         return true;
38                 }
39         }
40         return false;
41 }
42
43 bool ismyip_v4(struct in_addr ip)
44 {
45         struct sockaddr_storage ss;
46         in_addr_to_sockaddr_storage(&ss, ip);
47         return ismyaddr(&ss);
48 }
49
50 /****************************************************************************
51  Try and find an interface that matches an ip. If we cannot, return NULL.
52 **************************************************************************/
53
54 static struct interface *iface_find(const struct sockaddr_storage *ip,
55                                 bool check_mask)
56 {
57         struct interface *i;
58
59         if (is_address_any(ip)) {
60                 return local_interfaces;
61         }
62
63         for (i=local_interfaces;i;i=i->next) {
64                 if (check_mask) {
65                         if (same_net(ip, &i->ip, &i->netmask)) {
66                                 return i;
67                         }
68                 } else if (addr_equal(&i->ip, ip)) {
69                         return i;
70                 }
71         }
72
73         return NULL;
74 }
75
76 /****************************************************************************
77  Check if a packet is from a local (known) net.
78 **************************************************************************/
79
80 bool is_local_net(const struct sockaddr_storage *from)
81 {
82         struct interface *i;
83         for (i=local_interfaces;i;i=i->next) {
84                 if (same_net(from, &i->ip, &i->netmask)) {
85                         return true;
86                 }
87         }
88         return false;
89 }
90
91 /****************************************************************************
92  Check if a packet is from a local (known) net.
93 **************************************************************************/
94
95 bool is_local_net_v4(struct in_addr from)
96 {
97         struct sockaddr_storage ss;
98
99         in_addr_to_sockaddr_storage(&ss, from);
100         return is_local_net(&ss);
101 }
102
103 /****************************************************************************
104  How many interfaces do we have ?
105 **************************************************************************/
106
107 int iface_count(void)
108 {
109         int ret = 0;
110         struct interface *i;
111
112         for (i=local_interfaces;i;i=i->next) {
113                 ret++;
114         }
115         return ret;
116 }
117
118 /****************************************************************************
119  How many interfaces do we have (v4 only) ?
120 **************************************************************************/
121
122 int iface_count_v4(void)
123 {
124         int ret = 0;
125         struct interface *i;
126
127         for (i=local_interfaces;i;i=i->next) {
128                 if (i->ip.ss_family == AF_INET) {
129                         ret++;
130                 }
131         }
132         return ret;
133 }
134
135 /****************************************************************************
136  Return a pointer to the in_addr of the first IPv4 interface.
137 **************************************************************************/
138
139 const struct in_addr *first_ipv4_iface(void)
140 {
141         struct interface *i;
142
143         for (i=local_interfaces;i ;i=i->next) {
144                 if (i->ip.ss_family == AF_INET) {
145                         break;
146                 }
147         }
148
149         if (!i) {
150                 return NULL;
151         }
152         return &((const struct sockaddr_in *)&i->ip)->sin_addr;
153 }
154
155 /****************************************************************************
156  Return the Nth interface.
157 **************************************************************************/
158
159 struct interface *get_interface(int n)
160 {
161         struct interface *i;
162
163         for (i=local_interfaces;i && n;i=i->next) {
164                 n--;
165         }
166
167         if (i) {
168                 return i;
169         }
170         return NULL;
171 }
172
173 /****************************************************************************
174  Return IP sockaddr_storage of the Nth interface.
175 **************************************************************************/
176
177 const struct sockaddr_storage *iface_n_sockaddr_storage(int n)
178 {
179         struct interface *i;
180
181         for (i=local_interfaces;i && n;i=i->next) {
182                 n--;
183         }
184
185         if (i) {
186                 return &i->ip;
187         }
188         return NULL;
189 }
190
191 /****************************************************************************
192  Return IPv4 of the Nth interface (if a v4 address). NULL otherwise.
193 **************************************************************************/
194
195 const struct in_addr *iface_n_ip_v4(int n)
196 {
197         struct interface *i;
198
199         for (i=local_interfaces;i && n;i=i->next) {
200                 n--;
201         }
202
203         if (i && i->ip.ss_family == AF_INET) {
204                 return &((const struct sockaddr_in *)&i->ip)->sin_addr;
205         }
206         return NULL;
207 }
208
209 /****************************************************************************
210  Return IPv4 bcast of the Nth interface (if a v4 address). NULL otherwise.
211 **************************************************************************/
212
213 const struct in_addr *iface_n_bcast_v4(int n)
214 {
215         struct interface *i;
216
217         for (i=local_interfaces;i && n;i=i->next) {
218                 n--;
219         }
220
221         if (i && i->ip.ss_family == AF_INET) {
222                 return &((const struct sockaddr_in *)&i->bcast)->sin_addr;
223         }
224         return NULL;
225 }
226
227 /****************************************************************************
228  Return bcast of the Nth interface.
229 **************************************************************************/
230
231 const struct sockaddr_storage *iface_n_bcast(int n)
232 {
233         struct interface *i;
234
235         for (i=local_interfaces;i && n;i=i->next) {
236                 n--;
237         }
238
239         if (i) {
240                 return &i->bcast;
241         }
242         return NULL;
243 }
244
245 /* these 3 functions return the ip/bcast/nmask for the interface
246    most appropriate for the given ip address. If they can't find
247    an appropriate interface they return the requested field of the
248    first known interface. */
249
250 const struct sockaddr_storage *iface_ip(const struct sockaddr_storage *ip)
251 {
252         struct interface *i = iface_find(ip, true);
253         if (i) {
254                 return &i->ip;
255         }
256
257         /* Search for the first interface with
258          * matching address family. */
259
260         for (i=local_interfaces;i;i=i->next) {
261                 if (i->ip.ss_family == ip->ss_family) {
262                         return &i->ip;
263                 }
264         }
265         return NULL;
266 }
267
268 /*
269   return True if a IP is directly reachable on one of our interfaces
270 */
271
272 bool iface_local(struct sockaddr_storage *ip)
273 {
274         return iface_find(ip, True) ? true : false;
275 }
276
277 /****************************************************************************
278  Add an interface to the linked list of interfaces.
279 ****************************************************************************/
280
281 static void add_interface(const struct iface_struct *ifs)
282 {
283         char addr[INET6_ADDRSTRLEN];
284         struct interface *iface;
285
286         if (iface_find(&ifs->ip, False)) {
287                 DEBUG(3,("add_interface: not adding duplicate interface %s\n",
288                         print_sockaddr(addr, sizeof(addr),
289                                 &ifs->ip, sizeof(struct sockaddr_storage)) ));
290                 return;
291         }
292
293         if (!(ifs->flags & (IFF_BROADCAST|IFF_LOOPBACK))) {
294                 DEBUG(3,("not adding non-broadcast interface %s\n",
295                                         ifs->name ));
296                 return;
297         }
298
299         iface = SMB_MALLOC_P(struct interface);
300         if (!iface) {
301                 return;
302         }
303
304         ZERO_STRUCTPN(iface);
305
306         iface->name = SMB_STRDUP(ifs->name);
307         if (!iface->name) {
308                 SAFE_FREE(iface);
309                 return;
310         }
311         iface->flags = ifs->flags;
312         iface->ip = ifs->ip;
313         iface->netmask = ifs->netmask;
314         iface->bcast = ifs->bcast;
315
316         DLIST_ADD(local_interfaces, iface);
317
318         DEBUG(2,("added interface %s ip=%s ",
319                 iface->name,
320                 print_sockaddr(addr, sizeof(addr),
321                         &iface->ip, sizeof(struct sockaddr_storage)) ));
322         DEBUG(2,("bcast=%s ",
323                 print_sockaddr(addr, sizeof(addr),
324                         &iface->bcast,
325                         sizeof(struct sockaddr_storage)) ));
326         DEBUG(2,("netmask=%s\n",
327                 print_sockaddr(addr, sizeof(addr),
328                         &iface->netmask,
329                         sizeof(struct sockaddr_storage)) ));
330 }
331
332 /****************************************************************************
333  Create a struct sockaddr_storage with the netmask bits set to 1.
334 ****************************************************************************/
335
336 static bool make_netmask(struct sockaddr_storage *pss_out,
337                         const struct sockaddr_storage *pss_in,
338                         unsigned long masklen)
339 {
340         *pss_out = *pss_in;
341         /* Now apply masklen bits of mask. */
342 #if defined(AF_INET6)
343         if (pss_in->ss_family == AF_INET6) {
344                 char *p = (char *)&((struct sockaddr_in6 *)pss_out)->sin6_addr;
345                 unsigned int i;
346
347                 if (masklen > 128) {
348                         return false;
349                 }
350                 for (i = 0; masklen >= 8; masklen -= 8, i++) {
351                         *p++ = 0xff;
352                 }
353                 /* Deal with the partial byte. */
354                 *p++ &= (0xff & ~(0xff>>masklen));
355                 i++;
356                 for (;i < sizeof(struct in6_addr); i++) {
357                         *p++ = '\0';
358                 }
359                 return true;
360         }
361 #endif
362         if (pss_in->ss_family == AF_INET) {
363                 if (masklen > 32) {
364                         return false;
365                 }
366                 ((struct sockaddr_in *)pss_out)->sin_addr.s_addr =
367                         htonl(((0xFFFFFFFFL >> masklen) ^ 0xFFFFFFFFL));
368                 return true;
369         }
370         return false;
371 }
372
373 /****************************************************************************
374  Create a struct sockaddr_storage set to the broadcast or network adress from
375  an incoming sockaddr_storage.
376 ****************************************************************************/
377
378 static void make_bcast_or_net(struct sockaddr_storage *pss_out,
379                         const struct sockaddr_storage *pss_in,
380                         const struct sockaddr_storage *nmask,
381                         bool make_bcast)
382 {
383         unsigned int i = 0, len = 0;
384         char *pmask = NULL;
385         char *p = NULL;
386         *pss_out = *pss_in;
387
388         /* Set all zero netmask bits to 1. */
389 #if defined(AF_INET6)
390         if (pss_in->ss_family == AF_INET6) {
391                 p = (char *)&((struct sockaddr_in6 *)pss_out)->sin6_addr;
392                 pmask = (char *)&((struct sockaddr_in6 *)nmask)->sin6_addr;
393                 len = 16;
394         }
395 #endif
396         if (pss_in->ss_family == AF_INET) {
397                 p = (char *)&((struct sockaddr_in *)pss_out)->sin_addr;
398                 pmask = (char *)&((struct sockaddr_in *)nmask)->sin_addr;
399                 len = 4;
400         }
401
402         for (i = 0; i < len; i++, p++, pmask++) {
403                 if (make_bcast) {
404                         *p = (*p & *pmask) | (*pmask ^ 0xff);
405                 } else {
406                         /* make_net */
407                         *p = (*p & *pmask);
408                 }
409         }
410 }
411
412 static void make_bcast(struct sockaddr_storage *pss_out,
413                         const struct sockaddr_storage *pss_in,
414                         const struct sockaddr_storage *nmask)
415 {
416         make_bcast_or_net(pss_out, pss_in, nmask, true);
417 }
418
419 static void make_net(struct sockaddr_storage *pss_out,
420                         const struct sockaddr_storage *pss_in,
421                         const struct sockaddr_storage *nmask)
422 {
423         make_bcast_or_net(pss_out, pss_in, nmask, false);
424 }
425
426 /****************************************************************************
427  Interpret a single element from a interfaces= config line.
428
429  This handles the following different forms:
430
431  1) wildcard interface name
432  2) DNS name
433  3) IP/masklen
434  4) ip/mask
435  5) bcast/mask
436 ****************************************************************************/
437
438 static void interpret_interface(char *token)
439 {
440         struct sockaddr_storage ss;
441         struct sockaddr_storage ss_mask;
442         struct sockaddr_storage ss_net;
443         struct sockaddr_storage ss_bcast;
444         struct iface_struct ifs;
445         char *p;
446         int i;
447         bool added=false;
448         bool goodaddr = false;
449
450         /* first check if it is an interface name */
451         for (i=0;i<total_probed;i++) {
452                 if (gen_fnmatch(token, probed_ifaces[i].name) == 0) {
453                         add_interface(&probed_ifaces[i]);
454                         added = true;
455                 }
456         }
457         if (added) {
458                 return;
459         }
460
461         /* maybe it is a DNS name */
462         p = strchr_m(token,'/');
463         if (p == NULL) {
464                 if (!interpret_string_addr(&ss, token)) {
465                         DEBUG(2, ("interpret_interface: Can't find address "
466                                   "for %s\n", token));
467                         return;
468                 }
469
470                 for (i=0;i<total_probed;i++) {
471                         if (addr_equal(&ss, &probed_ifaces[i].ip)) {
472                                 add_interface(&probed_ifaces[i]);
473                                 return;
474                         }
475                 }
476                 DEBUG(2,("interpret_interface: "
477                         "can't determine interface for %s\n",
478                         token));
479                 return;
480         }
481
482         /* parse it into an IP address/netmasklength pair */
483         *p = 0;
484         goodaddr = interpret_string_addr(&ss, token);
485         *p++ = '/';
486
487         if (!goodaddr) {
488                 DEBUG(2,("interpret_interface: "
489                         "can't determine interface for %s\n",
490                         token));
491                 return;
492         }
493
494         if (strlen(p) > 2) {
495                 goodaddr = interpret_string_addr(&ss_mask, p);
496                 if (!goodaddr) {
497                         DEBUG(2,("interpret_interface: "
498                                 "can't determine netmask from %s\n",
499                                 p));
500                         return;
501                 }
502         } else {
503                 char *endp = NULL;
504                 unsigned long val = strtoul(p, &endp, 0);
505                 if (p == endp || (endp && *endp != '\0')) {
506                         DEBUG(2,("interpret_interface: "
507                                 "can't determine netmask value from %s\n",
508                                 p));
509                         return;
510                 }
511                 if (!make_netmask(&ss_mask, &ss, val)) {
512                         DEBUG(2,("interpret_interface: "
513                                 "can't apply netmask value %lu from %s\n",
514                                 val,
515                                 p));
516                         return;
517                 }
518         }
519
520         make_bcast(&ss_bcast, &ss, &ss_mask);
521         make_net(&ss_net, &ss, &ss_mask);
522
523         /* Maybe the first component was a broadcast address. */
524         if (addr_equal(&ss_bcast, &ss) || addr_equal(&ss_net, &ss)) {
525                 for (i=0;i<total_probed;i++) {
526                         if (same_net(&ss, &probed_ifaces[i].ip, &ss_mask)) {
527                                 /* Temporarily replace netmask on
528                                  * the detected interface - user knows
529                                  * best.... */
530                                 struct sockaddr_storage saved_mask =
531                                         probed_ifaces[i].netmask;
532                                 probed_ifaces[i].netmask = ss_mask;
533                                 DEBUG(2,("interpret_interface: "
534                                         "using netmask value %s from "
535                                         "config file on interface %s\n",
536                                         p,
537                                         probed_ifaces[i].name));
538                                 add_interface(&probed_ifaces[i]);
539                                 probed_ifaces[i].netmask = saved_mask;
540                                 return;
541                         }
542                 }
543                 DEBUG(2,("interpret_interface: Can't determine ip for "
544                         "broadcast address %s\n",
545                         token));
546                 return;
547         }
548
549         /* Just fake up the interface definition. User knows best. */
550
551         DEBUG(2,("interpret_interface: Adding interface %s\n",
552                 token));
553
554         ZERO_STRUCT(ifs);
555         safe_strcpy(ifs.name, token, sizeof(ifs.name)-1);
556         ifs.flags = IFF_BROADCAST;
557         ifs.ip = ss;
558         ifs.netmask = ss_mask;
559         ifs.bcast = ss_bcast;
560         add_interface(&ifs);
561 }
562
563 /****************************************************************************
564  Load the list of network interfaces.
565 ****************************************************************************/
566
567 void load_interfaces(void)
568 {
569         struct iface_struct ifaces[MAX_INTERFACES];
570         const char **ptr = lp_interfaces();
571         int i;
572
573         SAFE_FREE(probed_ifaces);
574
575         /* dump the current interfaces if any */
576         while (local_interfaces) {
577                 struct interface *iface = local_interfaces;
578                 DLIST_REMOVE(local_interfaces, local_interfaces);
579                 SAFE_FREE(iface->name);
580                 SAFE_FREE(iface);
581         }
582
583         /* Probe the kernel for interfaces */
584         total_probed = get_interfaces(ifaces, MAX_INTERFACES);
585
586         if (total_probed > 0) {
587                 probed_ifaces = (struct iface_struct *)memdup(ifaces,
588                                 sizeof(ifaces[0])*total_probed);
589                 if (!probed_ifaces) {
590                         DEBUG(0,("ERROR: memdup failed\n"));
591                         exit(1);
592                 }
593         }
594
595         /* if we don't have a interfaces line then use all broadcast capable
596            interfaces except loopback */
597         if (!ptr || !*ptr || !**ptr) {
598                 if (total_probed <= 0) {
599                         DEBUG(0,("ERROR: Could not determine network "
600                         "interfaces, you must use a interfaces config line\n"));
601                         exit(1);
602                 }
603                 for (i=0;i<total_probed;i++) {
604                         if (probed_ifaces[i].flags & IFF_BROADCAST) {
605                                 add_interface(&probed_ifaces[i]);
606                         }
607                 }
608                 return;
609         }
610
611         if (ptr) {
612                 while (*ptr) {
613                         char *ptr_cpy = SMB_STRDUP(*ptr);
614                         if (ptr_cpy) {
615                                 interpret_interface(ptr_cpy);
616                                 free(ptr_cpy);
617                         }
618                         ptr++;
619                 }
620         }
621
622         if (!local_interfaces) {
623                 DEBUG(0,("WARNING: no network interfaces found\n"));
624         }
625 }
626
627
628 void gfree_interfaces(void)
629 {
630         while (local_interfaces) {
631                 struct interface *iface = local_interfaces;
632                 DLIST_REMOVE(local_interfaces, local_interfaces);
633                 SAFE_FREE(iface->name);
634                 SAFE_FREE(iface);
635         }
636
637         SAFE_FREE(probed_ifaces);
638 }
639
640 /****************************************************************************
641  Return True if the list of probed interfaces has changed.
642 ****************************************************************************/
643
644 bool interfaces_changed(void)
645 {
646         int n;
647         struct iface_struct ifaces[MAX_INTERFACES];
648
649         n = get_interfaces(ifaces, MAX_INTERFACES);
650
651         if ((n > 0 )&& (n != total_probed ||
652                         memcmp(ifaces, probed_ifaces, sizeof(ifaces[0])*n))) {
653                 return true;
654         }
655
656         return false;
657 }