This is a large patch (sorry). Migrate from struct in_addr
[tprouty/samba.git] / source3 / 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(const 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), &ifs->ip) ));
289                 return;
290         }
291
292         if (!(ifs->flags & (IFF_BROADCAST|IFF_LOOPBACK))) {
293                 DEBUG(3,("not adding non-broadcast interface %s\n",
294                                         ifs->name ));
295                 return;
296         }
297
298         iface = SMB_MALLOC_P(struct interface);
299         if (!iface) {
300                 return;
301         }
302
303         ZERO_STRUCTPN(iface);
304
305         iface->name = SMB_STRDUP(ifs->name);
306         if (!iface->name) {
307                 SAFE_FREE(iface);
308                 return;
309         }
310         iface->flags = ifs->flags;
311         iface->ip = ifs->ip;
312         iface->netmask = ifs->netmask;
313         iface->bcast = ifs->bcast;
314
315         DLIST_ADD(local_interfaces, iface);
316
317         DEBUG(2,("added interface %s ip=%s ",
318                 iface->name,
319                 print_sockaddr(addr, sizeof(addr), &iface->ip) ));
320         DEBUG(2,("bcast=%s ",
321                 print_sockaddr(addr, sizeof(addr),
322                         &iface->bcast) ));
323         DEBUG(2,("netmask=%s\n",
324                 print_sockaddr(addr, sizeof(addr),
325                         &iface->netmask) ));
326 }
327
328 /****************************************************************************
329  Create a struct sockaddr_storage with the netmask bits set to 1.
330 ****************************************************************************/
331
332 bool make_netmask(struct sockaddr_storage *pss_out,
333                         const struct sockaddr_storage *pss_in,
334                         unsigned long masklen)
335 {
336         *pss_out = *pss_in;
337         /* Now apply masklen bits of mask. */
338 #if defined(HAVE_IPV6)
339         if (pss_in->ss_family == AF_INET6) {
340                 char *p = (char *)&((struct sockaddr_in6 *)pss_out)->sin6_addr;
341                 unsigned int i;
342
343                 if (masklen > 128) {
344                         return false;
345                 }
346                 for (i = 0; masklen >= 8; masklen -= 8, i++) {
347                         *p++ = 0xff;
348                 }
349                 /* Deal with the partial byte. */
350                 *p++ &= (0xff & ~(0xff>>masklen));
351                 i++;
352                 for (;i < sizeof(struct in6_addr); i++) {
353                         *p++ = '\0';
354                 }
355                 return true;
356         }
357 #endif
358         if (pss_in->ss_family == AF_INET) {
359                 if (masklen > 32) {
360                         return false;
361                 }
362                 ((struct sockaddr_in *)pss_out)->sin_addr.s_addr =
363                         htonl(((0xFFFFFFFFL >> masklen) ^ 0xFFFFFFFFL));
364                 return true;
365         }
366         return false;
367 }
368
369 /****************************************************************************
370  Create a struct sockaddr_storage set to the broadcast or network adress from
371  an incoming sockaddr_storage.
372 ****************************************************************************/
373
374 static void make_bcast_or_net(struct sockaddr_storage *pss_out,
375                         const struct sockaddr_storage *pss_in,
376                         const struct sockaddr_storage *nmask,
377                         bool make_bcast)
378 {
379         unsigned int i = 0, len = 0;
380         char *pmask = NULL;
381         char *p = NULL;
382         *pss_out = *pss_in;
383
384         /* Set all zero netmask bits to 1. */
385 #if defined(HAVE_IPV6)
386         if (pss_in->ss_family == AF_INET6) {
387                 p = (char *)&((struct sockaddr_in6 *)pss_out)->sin6_addr;
388                 pmask = (char *)&((struct sockaddr_in6 *)nmask)->sin6_addr;
389                 len = 16;
390         }
391 #endif
392         if (pss_in->ss_family == AF_INET) {
393                 p = (char *)&((struct sockaddr_in *)pss_out)->sin_addr;
394                 pmask = (char *)&((struct sockaddr_in *)nmask)->sin_addr;
395                 len = 4;
396         }
397
398         for (i = 0; i < len; i++, p++, pmask++) {
399                 if (make_bcast) {
400                         *p = (*p & *pmask) | (*pmask ^ 0xff);
401                 } else {
402                         /* make_net */
403                         *p = (*p & *pmask);
404                 }
405         }
406 }
407
408 static void make_bcast(struct sockaddr_storage *pss_out,
409                         const struct sockaddr_storage *pss_in,
410                         const struct sockaddr_storage *nmask)
411 {
412         make_bcast_or_net(pss_out, pss_in, nmask, true);
413 }
414
415 static void make_net(struct sockaddr_storage *pss_out,
416                         const struct sockaddr_storage *pss_in,
417                         const struct sockaddr_storage *nmask)
418 {
419         make_bcast_or_net(pss_out, pss_in, nmask, false);
420 }
421
422 /****************************************************************************
423  Interpret a single element from a interfaces= config line.
424
425  This handles the following different forms:
426
427  1) wildcard interface name
428  2) DNS name
429  3) IP/masklen
430  4) ip/mask
431  5) bcast/mask
432 ****************************************************************************/
433
434 static void interpret_interface(char *token)
435 {
436         struct sockaddr_storage ss;
437         struct sockaddr_storage ss_mask;
438         struct sockaddr_storage ss_net;
439         struct sockaddr_storage ss_bcast;
440         struct iface_struct ifs;
441         char *p;
442         int i;
443         bool added=false;
444         bool goodaddr = false;
445
446         /* first check if it is an interface name */
447         for (i=0;i<total_probed;i++) {
448                 if (gen_fnmatch(token, probed_ifaces[i].name) == 0) {
449                         add_interface(&probed_ifaces[i]);
450                         added = true;
451                 }
452         }
453         if (added) {
454                 return;
455         }
456
457         /* maybe it is a DNS name */
458         p = strchr_m(token,'/');
459         if (p == NULL) {
460                 if (!interpret_string_addr(&ss, token, 0)) {
461                         DEBUG(2, ("interpret_interface: Can't find address "
462                                   "for %s\n", token));
463                         return;
464                 }
465
466                 for (i=0;i<total_probed;i++) {
467                         if (addr_equal(&ss, &probed_ifaces[i].ip)) {
468                                 add_interface(&probed_ifaces[i]);
469                                 return;
470                         }
471                 }
472                 DEBUG(2,("interpret_interface: "
473                         "can't determine interface for %s\n",
474                         token));
475                 return;
476         }
477
478         /* parse it into an IP address/netmasklength pair */
479         *p = 0;
480         goodaddr = interpret_string_addr(&ss, token, 0);
481         *p++ = '/';
482
483         if (!goodaddr) {
484                 DEBUG(2,("interpret_interface: "
485                         "can't determine interface for %s\n",
486                         token));
487                 return;
488         }
489
490         if (strlen(p) > 2) {
491                 goodaddr = interpret_string_addr(&ss_mask, p, 0);
492                 if (!goodaddr) {
493                         DEBUG(2,("interpret_interface: "
494                                 "can't determine netmask from %s\n",
495                                 p));
496                         return;
497                 }
498         } else {
499                 char *endp = NULL;
500                 unsigned long val = strtoul(p, &endp, 0);
501                 if (p == endp || (endp && *endp != '\0')) {
502                         DEBUG(2,("interpret_interface: "
503                                 "can't determine netmask value from %s\n",
504                                 p));
505                         return;
506                 }
507                 if (!make_netmask(&ss_mask, &ss, val)) {
508                         DEBUG(2,("interpret_interface: "
509                                 "can't apply netmask value %lu from %s\n",
510                                 val,
511                                 p));
512                         return;
513                 }
514         }
515
516         make_bcast(&ss_bcast, &ss, &ss_mask);
517         make_net(&ss_net, &ss, &ss_mask);
518
519         /* Maybe the first component was a broadcast address. */
520         if (addr_equal(&ss_bcast, &ss) || addr_equal(&ss_net, &ss)) {
521                 for (i=0;i<total_probed;i++) {
522                         if (same_net(&ss, &probed_ifaces[i].ip, &ss_mask)) {
523                                 /* Temporarily replace netmask on
524                                  * the detected interface - user knows
525                                  * best.... */
526                                 struct sockaddr_storage saved_mask =
527                                         probed_ifaces[i].netmask;
528                                 probed_ifaces[i].netmask = ss_mask;
529                                 DEBUG(2,("interpret_interface: "
530                                         "using netmask value %s from "
531                                         "config file on interface %s\n",
532                                         p,
533                                         probed_ifaces[i].name));
534                                 add_interface(&probed_ifaces[i]);
535                                 probed_ifaces[i].netmask = saved_mask;
536                                 return;
537                         }
538                 }
539                 DEBUG(2,("interpret_interface: Can't determine ip for "
540                         "broadcast address %s\n",
541                         token));
542                 return;
543         }
544
545         /* Just fake up the interface definition. User knows best. */
546
547         DEBUG(2,("interpret_interface: Adding interface %s\n",
548                 token));
549
550         ZERO_STRUCT(ifs);
551         safe_strcpy(ifs.name, token, sizeof(ifs.name)-1);
552         ifs.flags = IFF_BROADCAST;
553         ifs.ip = ss;
554         ifs.netmask = ss_mask;
555         ifs.bcast = ss_bcast;
556         add_interface(&ifs);
557 }
558
559 /****************************************************************************
560  Load the list of network interfaces.
561 ****************************************************************************/
562
563 void load_interfaces(void)
564 {
565         struct iface_struct ifaces[MAX_INTERFACES];
566         const char **ptr = lp_interfaces();
567         int i;
568
569         SAFE_FREE(probed_ifaces);
570
571         /* dump the current interfaces if any */
572         while (local_interfaces) {
573                 struct interface *iface = local_interfaces;
574                 DLIST_REMOVE(local_interfaces, local_interfaces);
575                 SAFE_FREE(iface->name);
576                 SAFE_FREE(iface);
577         }
578
579         /* Probe the kernel for interfaces */
580         total_probed = get_interfaces(ifaces, MAX_INTERFACES);
581
582         if (total_probed > 0) {
583                 probed_ifaces = (struct iface_struct *)memdup(ifaces,
584                                 sizeof(ifaces[0])*total_probed);
585                 if (!probed_ifaces) {
586                         DEBUG(0,("ERROR: memdup failed\n"));
587                         exit(1);
588                 }
589         }
590
591         /* if we don't have a interfaces line then use all broadcast capable
592            interfaces except loopback */
593         if (!ptr || !*ptr || !**ptr) {
594                 if (total_probed <= 0) {
595                         DEBUG(0,("ERROR: Could not determine network "
596                         "interfaces, you must use a interfaces config line\n"));
597                         exit(1);
598                 }
599                 for (i=0;i<total_probed;i++) {
600                         if (probed_ifaces[i].flags & IFF_BROADCAST) {
601                                 add_interface(&probed_ifaces[i]);
602                         }
603                 }
604                 return;
605         }
606
607         if (ptr) {
608                 while (*ptr) {
609                         char *ptr_cpy = SMB_STRDUP(*ptr);
610                         if (ptr_cpy) {
611                                 interpret_interface(ptr_cpy);
612                                 free(ptr_cpy);
613                         }
614                         ptr++;
615                 }
616         }
617
618         if (!local_interfaces) {
619                 DEBUG(0,("WARNING: no network interfaces found\n"));
620         }
621 }
622
623
624 void gfree_interfaces(void)
625 {
626         while (local_interfaces) {
627                 struct interface *iface = local_interfaces;
628                 DLIST_REMOVE(local_interfaces, local_interfaces);
629                 SAFE_FREE(iface->name);
630                 SAFE_FREE(iface);
631         }
632
633         SAFE_FREE(probed_ifaces);
634 }
635
636 /****************************************************************************
637  Return True if the list of probed interfaces has changed.
638 ****************************************************************************/
639
640 bool interfaces_changed(void)
641 {
642         int n;
643         struct iface_struct ifaces[MAX_INTERFACES];
644
645         n = get_interfaces(ifaces, MAX_INTERFACES);
646
647         if ((n > 0 )&& (n != total_probed ||
648                         memcmp(ifaces, probed_ifaces, sizeof(ifaces[0])*n))) {
649                 return true;
650         }
651
652         return false;
653 }