source: branches/samba-3.2.x/source/lib/interface.c

Last change on this file was 233, checked in by Herwig Bauernfeind, 17 years ago

Update 3.2 branch to 3.2.9

File size: 14.3 KB
Line 
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
23static struct iface_struct *probed_ifaces;
24static int total_probed;
25
26static struct interface *local_interfaces;
27
28/****************************************************************************
29 Check if an IP is one of mine.
30**************************************************************************/
31
32bool ismyaddr(const struct sockaddr_storage *ip)
33{
34 struct interface *i;
35 for (i=local_interfaces;i;i=i->next) {
36 if (sockaddr_equal(&i->ip,ip)) {
37 return true;
38 }
39 }
40 return false;
41}
42
43bool 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
54static 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 (sockaddr_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
80bool 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#if defined(HAVE_IPV6)
92void setup_linklocal_scope_id(struct sockaddr_storage *pss)
93{
94 struct interface *i;
95 for (i=local_interfaces;i;i=i->next) {
96 if (sockaddr_equal(&i->ip,pss)) {
97 struct sockaddr_in6 *psa6 =
98 (struct sockaddr_in6 *)pss;
99 psa6->sin6_scope_id = if_nametoindex(i->name);
100 return;
101 }
102 }
103}
104#endif
105
106/****************************************************************************
107 Check if a packet is from a local (known) net.
108**************************************************************************/
109
110bool is_local_net_v4(struct in_addr from)
111{
112 struct sockaddr_storage ss;
113
114 in_addr_to_sockaddr_storage(&ss, from);
115 return is_local_net(&ss);
116}
117
118/****************************************************************************
119 How many interfaces do we have ?
120**************************************************************************/
121
122int iface_count(void)
123{
124 int ret = 0;
125 struct interface *i;
126
127 for (i=local_interfaces;i;i=i->next) {
128 ret++;
129 }
130 return ret;
131}
132
133/****************************************************************************
134 How many non-loopback IPv4 interfaces do we have ?
135**************************************************************************/
136
137int iface_count_v4_nl(void)
138{
139 int ret = 0;
140 struct interface *i;
141
142 for (i=local_interfaces;i;i=i->next) {
143 if (is_loopback_addr(&i->ip)) {
144 continue;
145 }
146 if (i->ip.ss_family == AF_INET) {
147 ret++;
148 }
149 }
150 return ret;
151}
152
153/****************************************************************************
154 Return a pointer to the in_addr of the first IPv4 interface that's
155 not 0.0.0.0.
156**************************************************************************/
157
158const struct in_addr *first_ipv4_iface(void)
159{
160 struct interface *i;
161
162 for (i=local_interfaces;i ;i=i->next) {
163 if ((i->ip.ss_family == AF_INET) &&
164 (!is_zero_ip_v4(((struct sockaddr_in *)&i->ip)->sin_addr)))
165 {
166 break;
167 }
168 }
169
170 if (!i) {
171 return NULL;
172 }
173 return &((const struct sockaddr_in *)&i->ip)->sin_addr;
174}