Code indentation.
[midnight-commander.git] / src / vfs / smbfs / helpers / lib / netmask.c
blobd23fd89c00ea09c9081856bebbfa63d8722ae136
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
4 code to query kernel netmask
6 Copyright (C) Andrew Tridgell 1998
8 Copyright (C) 2011
9 The Free Software Foundation, Inc.
11 This file is part of the Midnight Commander.
13 The Midnight Commander is free software: you can redistribute it
14 and/or modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation, either version 3 of the License,
16 or (at your option) any later version.
18 The Midnight Commander is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with this program. If not, see <http://www.gnu.org/licenses/>.
28 /* working out the netmask for an interface is an incredibly non-portable
29 thing. We have several possible implementations below, and autoconf
30 tries each of them to see what works
32 Note that this file does _not_ include includes.h. That is so this code
33 can be called directly from the autoconf tests. That also means
34 this code cannot use any of the normal Samba debug stuff or defines.
35 This is standalone code.
39 #ifndef AUTOCONF
40 #include "config.h"
41 #endif
43 #include <stdlib.h>
44 #include <string.h>
46 #ifdef HAVE_NETMASK_IFCONF
48 #include <stdio.h>
49 #include <unistd.h>
50 #include <sys/types.h>
51 #include <sys/socket.h>
52 #include <netinet/in.h>
53 #include <arpa/inet.h>
54 #include <netdb.h>
55 #include <sys/ioctl.h>
56 #include <net/if.h>
58 #ifndef SIOCGIFCONF
59 #include <sys/sockio.h>
60 #endif
63 * Prototype for gcc in fussy mode.
66 int get_netmask (struct in_addr *ipaddr, struct in_addr *nmask);
68 /****************************************************************************
69 get the netmask address for a local interface
70 ****************************************************************************/
71 int
72 get_netmask (struct in_addr *ipaddr, struct in_addr *nmask)
74 struct ifconf ifc;
75 char buff[2048];
76 int fd, i, n;
77 struct ifreq *ifr = NULL;
79 if ((fd = socket (AF_INET, SOCK_DGRAM, 0)) == -1)
81 #ifdef DEBUG
82 fprintf (stderr, "socket failed\n");
83 #endif
84 return -1;
87 ifc.ifc_len = sizeof (buff);
88 ifc.ifc_buf = buff;
89 if (ioctl (fd, SIOCGIFCONF, &ifc) != 0)
91 #ifdef DEBUG
92 fprintf (stderr, "SIOCGIFCONF failed\n");
93 #endif
94 close (fd);
95 return -1;
98 ifr = ifc.ifc_req;
100 n = ifc.ifc_len / sizeof (struct ifreq);
102 #ifdef DEBUG
103 fprintf (stderr, "%d interfaces - looking for %s\n", n, inet_ntoa (*ipaddr));
104 #endif
106 /* Loop through interfaces, looking for given IP address */
107 for (i = n - 1; i >= 0; i--)
109 if (ioctl (fd, SIOCGIFADDR, &ifr[i]) != 0)
111 #ifdef DEBUG
112 fprintf (stderr, "SIOCGIFADDR failed\n");
113 #endif
114 continue;
117 #ifdef DEBUG
118 fprintf (stderr, "interface %s\n",
119 inet_ntoa ((*(struct sockaddr_in *) &ifr[i].ifr_addr).sin_addr));
120 #endif
121 if (ipaddr->s_addr != (*(struct sockaddr_in *) &ifr[i].ifr_addr).sin_addr.s_addr)
123 continue;
126 if (ioctl (fd, SIOCGIFNETMASK, &ifr[i]) != 0)
128 #ifdef DEBUG
129 fprintf (stderr, "SIOCGIFNETMASK failed\n");
130 #endif
131 close (fd);
132 return -1;
134 close (fd);
135 (*nmask) = ((struct sockaddr_in *) &ifr[i].ifr_addr)->sin_addr;
136 #ifdef DEBUG
137 fprintf (stderr, "netmask %s\n", inet_ntoa (*nmask));
138 #endif
139 return 0;
142 #ifdef DEBUG
143 fprintf (stderr, "interface not found\n");
144 #endif
146 close (fd);
147 return -1;
150 #elif defined(HAVE_NETMASK_IFREQ)
152 #include <stdio.h>
153 #include <sys/types.h>
154 #include <sys/socket.h>
155 #include <netinet/in.h>
156 #include <arpa/inet.h>
157 #include <netdb.h>
158 #include <sys/ioctl.h>
159 #include <net/if.h>
161 #ifndef SIOCGIFCONF
162 #include <sys/sockio.h>
163 #endif
165 #ifndef I_STR
166 #include <sys/stropts.h>
167 #endif
170 /****************************************************************************
171 this should cover most of the rest of systems
172 ****************************************************************************/
174 get_netmask (struct in_addr *ipaddr, struct in_addr *nmask)
176 struct ifreq ifreq;
177 struct strioctl strioctl;
178 struct ifconf *ifc;
179 char buff[2048];
180 int fd, i, n;
181 struct ifreq *ifr = NULL;
183 if ((fd = socket (AF_INET, SOCK_DGRAM, 0)) == -1)
185 #ifdef DEBUG
186 fprintf (stderr, "socket failed\n");
187 #endif
188 return -1;
191 ifc = (struct ifconf *) buff;
192 ifc->ifc_len = BUFSIZ - sizeof (struct ifconf);
193 strioctl.ic_cmd = SIOCGIFCONF;
194 strioctl.ic_dp = (char *) ifc;
195 strioctl.ic_len = sizeof (buff);
196 if (ioctl (fd, I_STR, &strioctl) < 0)
198 #ifdef DEBUG
199 fprintf (stderr, "SIOCGIFCONF failed\n");
200 #endif
201 close (fd);
202 return -1;
205 ifr = (struct ifreq *) ifc->ifc_req;
207 /* Loop through interfaces, looking for given IP address */
208 n = ifc->ifc_len / sizeof (struct ifreq);
210 for (i = 0; i < n; i++, ifr++)
212 #ifdef DEBUG
213 fprintf (stderr, "interface %s\n",
214 inet_ntoa ((*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr.s_addr));
215 #endif
216 if (ipaddr->s_addr == (*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr.s_addr)
218 break;
222 #ifdef DEBUG
223 if (i == n)
225 fprintf (stderr, "interface not found\n");
226 close (fd);
227 return -1;
229 #endif
231 ifreq = *ifr;
233 strioctl.ic_cmd = SIOCGIFNETMASK;
234 strioctl.ic_dp = (char *) &ifreq;
235 strioctl.ic_len = sizeof (struct ifreq);
236 if (ioctl (fd, I_STR, &strioctl) != 0)
238 #ifdef DEBUG
239 fprintf (stderr, "Failed SIOCGIFNETMASK\n");
240 #endif
241 close (fd);
242 return -1;
245 close (fd);
246 *nmask = ((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr;
247 #ifdef DEBUG
248 fprintf (stderr, "netmask %s\n", inet_ntoa (*nmask));
249 #endif
250 return 0;
253 #elif defined(HAVE_NETMASK_AIX)
255 #include <stdio.h>
256 #include <unistd.h> /* close() declaration for gcc in fussy mode */
257 #include <sys/types.h>
258 #include <sys/socket.h>
259 #include <netinet/in.h>
260 #include <arpa/inet.h>
261 #include <netdb.h>
262 #include <sys/ioctl.h>
263 #include <net/if.h>
265 #ifndef SIOCGIFCONF
266 #include <sys/sockio.h>
267 #endif
270 * Prototype for gcc in fussy mode.
273 int get_netmask (struct in_addr *ipaddr, struct in_addr *nmask);
275 /****************************************************************************
276 this one is for AIX
277 ****************************************************************************/
280 get_netmask (struct in_addr *ipaddr, struct in_addr *nmask)
282 char buff[2048];
283 int fd, i;
284 struct ifconf ifc;
285 struct ifreq *ifr = NULL;
287 if ((fd = socket (AF_INET, SOCK_DGRAM, 0)) == -1)
289 #ifdef DEBUG
290 fprintf (stderr, "socket failed\n");
291 #endif
292 return -1;
296 ifc.ifc_len = sizeof (buff);
297 ifc.ifc_buf = buff;
299 if (ioctl (fd, SIOCGIFCONF, &ifc) != 0)
301 #ifdef DEBUG
302 fprintf (stderr, "SIOCGIFCONF failed\n");
303 #endif
304 close (fd);
305 return -1;
308 ifr = ifc.ifc_req;
309 /* Loop through interfaces, looking for given IP address */
310 i = ifc.ifc_len;
311 while (i > 0)
313 #ifdef DEBUG
314 fprintf (stderr, "interface %s\n",
315 inet_ntoa ((*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr));
316 #endif
317 if (ipaddr->s_addr == (*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr.s_addr)
319 break;
321 i -= ifr->ifr_addr.sa_len + IFNAMSIZ;
322 ifr = (struct ifreq *) ((char *) ifr + ifr->ifr_addr.sa_len + IFNAMSIZ);
326 #ifdef DEBUG
327 if (i <= 0)
329 fprintf (stderr, "interface not found\n");
330 close (fd);
331 return -1;
333 #endif
335 if (ioctl (fd, SIOCGIFNETMASK, ifr) != 0)
337 #ifdef DEBUG
338 fprintf (stderr, "SIOCGIFNETMASK failed\n");
339 #endif
340 close (fd);
341 return -1;
344 close (fd);
346 (*nmask) = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr;
347 #ifdef DEBUG
348 fprintf (stderr, "netmask %s\n", inet_ntoa (*nmask));
349 #endif
350 return 0;
353 #else /* a dummy version */
354 struct in_addr; /* it may not have been declared before */
355 int get_netmask (struct in_addr *ipaddr, struct in_addr *nmask);
357 get_netmask (struct in_addr *ipaddr, struct in_addr *nmask)
359 return -1;
361 #endif
364 #ifdef AUTOCONF
365 /* this is the autoconf driver to test get_netmask() */
367 main ()
369 char buf[1024];
370 struct hostent *hp;
371 struct in_addr ip, nmask;
373 if (gethostname (buf, sizeof (buf) - 1) != 0)
375 fprintf (stderr, "gethostname failed\n");
376 exit (1);
379 hp = gethostbyname (buf);
381 if (!hp)
383 fprintf (stderr, "gethostbyname failed\n");
384 exit (1);
387 memcpy ((char *) &ip, (char *) hp->h_addr, hp->h_length);
389 if (get_netmask (&ip, &nmask) == 0)
390 exit (0);
392 fprintf (stderr, "get_netmask failed\n");
393 exit (1);
395 #endif