2 Unix SMB/Netbios implementation.
4 code to query kernel netmask
5 Copyright (C) Andrew Tridgell 1998
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 2 of the License, or
10 (at your option) any later version.
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.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 /* working out the netmask for an interface is an incredibly non-portable
24 thing. We have several possible implementations below, and autoconf
25 tries each of them to see what works
27 Note that this file does _not_ include includes.h. That is so this code
28 can be called directly from the autoconf tests. That also means
29 this code cannot use any of the normal Samba debug stuff or defines.
30 This is standalone code.
38 #ifdef HAVE_NETMASK_IFCONF
42 #include <sys/types.h>
43 #include <sys/socket.h>
44 #include <netinet/in.h>
45 #include <arpa/inet.h>
47 #include <sys/ioctl.h>
51 #include <sys/sockio.h>
55 * Prototype for gcc in fussy mode.
58 int get_netmask(struct in_addr *ipaddr, struct in_addr *nmask);
60 /****************************************************************************
61 get the netmask address for a local interface
62 ****************************************************************************/
63 int get_netmask(struct in_addr *ipaddr, struct in_addr *nmask)
68 struct ifreq *ifr=NULL;
70 if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
72 fprintf(stderr,"socket failed\n");
77 ifc.ifc_len = sizeof(buff);
79 if (ioctl(fd, SIOCGIFCONF, &ifc) != 0) {
81 fprintf(stderr,"SIOCGIFCONF failed\n");
89 n = ifc.ifc_len / sizeof(struct ifreq);
92 fprintf(stderr,"%d interfaces - looking for %s\n",
93 n, inet_ntoa(*ipaddr));
96 /* Loop through interfaces, looking for given IP address */
97 for (i=n-1;i>=0;i--) {
98 if (ioctl(fd, SIOCGIFADDR, &ifr[i]) != 0) {
100 fprintf(stderr,"SIOCGIFADDR failed\n");
106 fprintf(stderr,"interface %s\n",
107 inet_ntoa((*(struct sockaddr_in *)&ifr[i].ifr_addr).sin_addr));
109 if (ipaddr->s_addr !=
110 (*(struct sockaddr_in *)&ifr[i].ifr_addr).sin_addr.s_addr) {
114 if (ioctl(fd, SIOCGIFNETMASK, &ifr[i]) != 0) {
116 fprintf(stderr,"SIOCGIFNETMASK failed\n");
122 (*nmask) = ((struct sockaddr_in *)&ifr[i].ifr_addr)->sin_addr;
124 fprintf(stderr,"netmask %s\n", inet_ntoa(*nmask));
130 fprintf(stderr,"interface not found\n");
137 #elif defined(HAVE_NETMASK_IFREQ)
140 #include <sys/types.h>
141 #include <sys/socket.h>
142 #include <netinet/in.h>
143 #include <arpa/inet.h>
145 #include <sys/ioctl.h>
149 #include <sys/sockio.h>
153 #include <sys/stropts.h>
157 /****************************************************************************
158 this should cover most of the rest of systems
159 ****************************************************************************/
160 int get_netmask(struct in_addr *ipaddr, struct in_addr *nmask)
163 struct strioctl strioctl;
167 struct ifreq *ifr=NULL;
169 if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
171 fprintf(stderr,"socket failed\n");
176 ifc = (struct ifconf *)buff;
177 ifc->ifc_len = BUFSIZ - sizeof(struct ifconf);
178 strioctl.ic_cmd = SIOCGIFCONF;
179 strioctl.ic_dp = (char *)ifc;
180 strioctl.ic_len = sizeof(buff);
181 if (ioctl(fd, I_STR, &strioctl) < 0) {
183 fprintf(stderr,"SIOCGIFCONF failed\n");
189 ifr = (struct ifreq *)ifc->ifc_req;
191 /* Loop through interfaces, looking for given IP address */
192 n = ifc->ifc_len / sizeof(struct ifreq);
194 for (i = 0; i<n; i++, ifr++) {
196 fprintf(stderr,"interface %s\n",
197 inet_ntoa((*(struct sockaddr_in *)&ifr->ifr_addr).sin_addr.s_addr));
199 if (ipaddr->s_addr ==
200 (*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr.s_addr) {
207 fprintf(stderr,"interface not found\n");
215 strioctl.ic_cmd = SIOCGIFNETMASK;
216 strioctl.ic_dp = (char *)&ifreq;
217 strioctl.ic_len = sizeof(struct ifreq);
218 if (ioctl(fd, I_STR, &strioctl) != 0) {
220 fprintf(stderr,"Failed SIOCGIFNETMASK\n");
227 *nmask = ((struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr;
229 fprintf(stderr,"netmask %s\n", inet_ntoa(*nmask));
234 #elif defined(HAVE_NETMASK_AIX)
237 #include <sys/types.h>
238 #include <sys/socket.h>
239 #include <netinet/in.h>
240 #include <arpa/inet.h>
242 #include <sys/ioctl.h>
246 #include <sys/sockio.h>
249 /****************************************************************************
251 ****************************************************************************/
252 int get_netmask(struct in_addr *ipaddr, struct in_addr *nmask)
257 struct ifreq *ifr=NULL;
259 if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
261 fprintf(stderr,"socket failed\n");
267 ifc.ifc_len = sizeof(buff);
270 if (ioctl(fd, SIOCGIFCONF, &ifc) != 0) {
272 fprintf(stderr,"SIOCGIFCONF failed\n");
279 /* Loop through interfaces, looking for given IP address */
283 fprintf(stderr,"interface %s\n",
284 inet_ntoa((*(struct sockaddr_in *)&ifr->ifr_addr).sin_addr));
286 if (ipaddr->s_addr ==
287 (*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr.s_addr) {
290 i -= ifr->ifr_addr.sa_len + IFNAMSIZ;
291 ifr = (struct ifreq*) ((char*) ifr + ifr->ifr_addr.sa_len +
298 fprintf(stderr,"interface not found\n");
304 if (ioctl(fd, SIOCGIFNETMASK, ifr) != 0) {
306 fprintf(stderr,"SIOCGIFNETMASK failed\n");
314 (*nmask) = ((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr;
316 fprintf(stderr,"netmask %s\n", inet_ntoa(*nmask));
321 #else /* a dummy version */
322 struct in_addr; /* it may not have been declared before */
323 int get_netmask(struct in_addr *ipaddr, struct in_addr *nmask)
331 /* this is the autoconf driver to test get_netmask() */
337 struct in_addr ip, nmask;
339 if (gethostname(buf, sizeof(buf)-1) != 0) {
340 fprintf(stderr,"gethostname failed\n");
344 hp = gethostbyname(buf);
347 fprintf(stderr,"gethostbyname failed\n");
351 memcpy((char *)&ip, (char *)hp->h_addr, hp->h_length);
353 if (get_netmask(&ip, &nmask) == 0) exit(0);
355 fprintf(stderr,"get_netmask failed\n");