2 Unix SMB/Netbios implementation.
4 code to query kernel netmask
6 Copyright (C) Andrew Tridgell 1998
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.
46 #ifdef HAVE_NETMASK_IFCONF
50 #include <sys/types.h>
51 #include <sys/socket.h>
52 #include <netinet/in.h>
53 #include <arpa/inet.h>
55 #include <sys/ioctl.h>
59 #include <sys/sockio.h>
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 ****************************************************************************/
72 get_netmask (struct in_addr
*ipaddr
, struct in_addr
*nmask
)
77 struct ifreq
*ifr
= NULL
;
79 if ((fd
= socket (AF_INET
, SOCK_DGRAM
, 0)) == -1)
82 fprintf (stderr
, "socket failed\n");
87 ifc
.ifc_len
= sizeof (buff
);
89 if (ioctl (fd
, SIOCGIFCONF
, &ifc
) != 0)
92 fprintf (stderr
, "SIOCGIFCONF failed\n");
100 n
= ifc
.ifc_len
/ sizeof (struct ifreq
);
103 fprintf (stderr
, "%d interfaces - looking for %s\n", n
, inet_ntoa (*ipaddr
));
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)
112 fprintf (stderr
, "SIOCGIFADDR failed\n");
118 fprintf (stderr
, "interface %s\n",
119 inet_ntoa ((*(struct sockaddr_in
*) &ifr
[i
].ifr_addr
).sin_addr
));
121 if (ipaddr
->s_addr
!= (*(struct sockaddr_in
*) &ifr
[i
].ifr_addr
).sin_addr
.s_addr
)
126 if (ioctl (fd
, SIOCGIFNETMASK
, &ifr
[i
]) != 0)
129 fprintf (stderr
, "SIOCGIFNETMASK failed\n");
135 (*nmask
) = ((struct sockaddr_in
*) &ifr
[i
].ifr_addr
)->sin_addr
;
137 fprintf (stderr
, "netmask %s\n", inet_ntoa (*nmask
));
143 fprintf (stderr
, "interface not found\n");
150 #elif defined(HAVE_NETMASK_IFREQ)
153 #include <sys/types.h>
154 #include <sys/socket.h>
155 #include <netinet/in.h>
156 #include <arpa/inet.h>
158 #include <sys/ioctl.h>
162 #include <sys/sockio.h>
166 #include <sys/stropts.h>
170 /****************************************************************************
171 this should cover most of the rest of systems
172 ****************************************************************************/
174 get_netmask (struct in_addr
*ipaddr
, struct in_addr
*nmask
)
177 struct strioctl strioctl
;
181 struct ifreq
*ifr
= NULL
;
183 if ((fd
= socket (AF_INET
, SOCK_DGRAM
, 0)) == -1)
186 fprintf (stderr
, "socket failed\n");
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)
199 fprintf (stderr
, "SIOCGIFCONF failed\n");
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
++)
213 fprintf (stderr
, "interface %s\n",
214 inet_ntoa ((*(struct sockaddr_in
*) &ifr
->ifr_addr
).sin_addr
.s_addr
));
216 if (ipaddr
->s_addr
== (*(struct sockaddr_in
*) &ifr
->ifr_addr
).sin_addr
.s_addr
)
225 fprintf (stderr
, "interface not found\n");
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)
239 fprintf (stderr
, "Failed SIOCGIFNETMASK\n");
246 *nmask
= ((struct sockaddr_in
*) &ifreq
.ifr_addr
)->sin_addr
;
248 fprintf (stderr
, "netmask %s\n", inet_ntoa (*nmask
));
253 #elif defined(HAVE_NETMASK_AIX)
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>
262 #include <sys/ioctl.h>
266 #include <sys/sockio.h>
270 * Prototype for gcc in fussy mode.
273 int get_netmask (struct in_addr
*ipaddr
, struct in_addr
*nmask
);
275 /****************************************************************************
277 ****************************************************************************/
280 get_netmask (struct in_addr
*ipaddr
, struct in_addr
*nmask
)
285 struct ifreq
*ifr
= NULL
;
287 if ((fd
= socket (AF_INET
, SOCK_DGRAM
, 0)) == -1)
290 fprintf (stderr
, "socket failed\n");
296 ifc
.ifc_len
= sizeof (buff
);
299 if (ioctl (fd
, SIOCGIFCONF
, &ifc
) != 0)
302 fprintf (stderr
, "SIOCGIFCONF failed\n");
309 /* Loop through interfaces, looking for given IP address */
314 fprintf (stderr
, "interface %s\n",
315 inet_ntoa ((*(struct sockaddr_in
*) &ifr
->ifr_addr
).sin_addr
));
317 if (ipaddr
->s_addr
== (*(struct sockaddr_in
*) &ifr
->ifr_addr
).sin_addr
.s_addr
)
321 i
-= ifr
->ifr_addr
.sa_len
+ IFNAMSIZ
;
322 ifr
= (struct ifreq
*) ((char *) ifr
+ ifr
->ifr_addr
.sa_len
+ IFNAMSIZ
);
329 fprintf (stderr
, "interface not found\n");
335 if (ioctl (fd
, SIOCGIFNETMASK
, ifr
) != 0)
338 fprintf (stderr
, "SIOCGIFNETMASK failed\n");
346 (*nmask
) = ((struct sockaddr_in
*) &ifr
->ifr_addr
)->sin_addr
;
348 fprintf (stderr
, "netmask %s\n", inet_ntoa (*nmask
));
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
)
365 /* this is the autoconf driver to test get_netmask() */
371 struct in_addr ip
, nmask
;
373 if (gethostname (buf
, sizeof (buf
) - 1) != 0)
375 fprintf (stderr
, "gethostname failed\n");
379 hp
= gethostbyname (buf
);
383 fprintf (stderr
, "gethostbyname failed\n");
387 memcpy ((char *) &ip
, (char *) hp
->h_addr
, hp
->h_length
);
389 if (get_netmask (&ip
, &nmask
) == 0)
392 fprintf (stderr
, "get_netmask failed\n");