blocxx
NwIface.cpp
Go to the documentation of this file.
1/*******************************************************************************
2* Copyright (C) 2005, Vintela, Inc. All rights reserved.
3* Copyright (C) 2006, Novell, Inc. All rights reserved.
4*
5* Redistribution and use in source and binary forms, with or without
6* modification, are permitted provided that the following conditions are met:
7*
8* * Redistributions of source code must retain the above copyright notice,
9* this list of conditions and the following disclaimer.
10* * Redistributions in binary form must reproduce the above copyright
11* notice, this list of conditions and the following disclaimer in the
12* documentation and/or other materials provided with the distribution.
13* * Neither the name of
14* Vintela, Inc.,
15* nor Novell, Inc.,
16* nor the names of its contributors or employees may be used to
17* endorse or promote products derived from this software without
18* specific prior written permission.
19*
20* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30* POSSIBILITY OF SUCH DAMAGE.
31*******************************************************************************/
32
33
38
39#include "blocxx/BLOCXX_config.h"
40
41#if !defined(BLOCXX_WIN32) && !defined(BLOCXX_NETWARE)
42
43extern "C"
44{
45#ifdef BLOCXX_HAVE_UNISTD_H
46 #include <unistd.h>
47#endif
48
49#include <stdlib.h>
50#include <stdio.h>
51#include <sys/types.h>
52
53#ifdef BLOCXX_HAVE_SYS_SOCKET_H
54 #include <sys/socket.h>
55#endif
56
57#include <arpa/inet.h>
58#include <errno.h>
59
60#ifdef BLOCXX_GNU_LINUX
61 #include <sys/ioctl.h>
62 #include <linux/if.h>
63 #include <string.h>
64
65#elif defined (BLOCXX_OPENSERVER)
66 #include <string.h>
67 #include <stropts.h>
68 #include <net/if.h>
69 #include <netinet/in.h>
70 #include <strings.h>
71 #include <arpa/inet.h>
72 #include <fcntl.h>
73 #include <paths.h>
74 #include <sys/mdi.h>
75
76#elif defined (BLOCXX_DARWIN)
77 #include <net/if.h>
78 #include <sys/ioctl.h>
79#else
80
81 #ifdef BLOCXX_HAVE_STROPTS_H
82 #include <stropts.h>
83 #endif
84
85 #include <net/if.h>
86 #include <netinet/in.h>
87
88 #if defined (BLOCXX_HAVE_SYS_SOCKIO_H)
89 #include <sys/sockio.h>
90 #endif
91
92 #include <strings.h>
93 #include <fcntl.h>
94#endif
95
96#include <string.h>
97} // extern "C"
98// These need to be after the system includes because of some weird openserver
99// include order problem
100#include "blocxx/NwIface.hpp"
101#include "blocxx/String.hpp"
102#include "blocxx/Exception.hpp"
103#include "blocxx/SocketUtils.hpp"
104
105namespace BLOCXX_NAMESPACE
106{
107
110{
111 int s, lerrno;
112 struct ifreq ifr;
113 struct sockaddr_in *sin(0);
114 if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
115 {
116 BLOCXX_THROW(SocketException, "socket");
117 }
119 bzero(&ifr, sizeof(ifr));
120 strncpy(ifr.ifr_name, m_name.c_str(), sizeof(ifr.ifr_name));
122 // Get IP address
123 if (ioctl(s, SIOCGIFADDR, &ifr) < 0)
124 {
125 lerrno = errno;
126 close(s);
127 BLOCXX_THROW(SocketException, "ioctl:SIOCGIFADDR");
128 }
129 sin = reinterpret_cast<struct sockaddr_in *>(&ifr.ifr_addr);
130 m_addr = sin->sin_addr.s_addr;
132 // Get the broadcast address
133 // Testing
134 if (ioctl(s, SIOCGIFBRDADDR, &ifr) < 0)
135 {
136 lerrno = errno;
137 close(s);
138 BLOCXX_THROW(SocketException, "ioctl:SIOCGIFBRDADDR");
139 }
140 sin = reinterpret_cast<struct sockaddr_in*>(&ifr.ifr_broadaddr);
141 m_bcastAddr = sin->sin_addr.s_addr;
143 // Get net mask
144 if (ioctl(s, SIOCGIFNETMASK, &ifr) < 0)
145 {
146 lerrno = errno;
147 close(s);
148 BLOCXX_THROW(SocketException, "ioctl:SIOCGIFNETMASK");
149 }
150#ifdef BLOCXX_GNU_LINUX
151 sin = reinterpret_cast<struct sockaddr_in *>(&ifr.ifr_netmask);
152#else
153 sin = reinterpret_cast<struct sockaddr_in *>(&ifr.ifr_broadaddr);
154#endif
155 m_netmask = sin->sin_addr.s_addr;
156 close(s);
157}
158
159String
161{
162 return m_name;
163}
164
165unsigned long
167{
168 return m_addr;
169}
170
171String
176
177unsigned long
182
183String
188
189/*
190String
191NwIface::getMACAddressString()
192{
193 return m_macAddress;
194}
195*/
197unsigned long
199{
200 return m_netmask;
201}
202
203String
208
209bool
210NwIface::sameNetwork(unsigned long addr)
211{
212 return ((addr & m_netmask) == (m_addr & m_netmask));
213}
214
215bool
217{
218 return sameNetwork(stringToAddress(straddr));
219}
220
221unsigned long
223{
224 return inet_addr(straddr.c_str());
225}
226
227void
229{
230 char *p(0);
231 int numreqs = 30;
232 struct ifconf ifc;
233 struct ifreq *ifr(0);
234 struct ifreq ifrcopy;
235 int n;
236 int oldlen = -1;
237 int lerrno = 0;
238 const char* appliesTo(0);
239 ifc.ifc_buf = NULL;
240 for (;;)
241 {
242 ifc.ifc_len = sizeof(struct ifreq) * numreqs;
243 if (ifc.ifc_buf == NULL)
244 {
245 ifc.ifc_buf = new char[ifc.ifc_len];
246 }
247 else
248 {
249 p = new char[ifc.ifc_len];
250 memmove(p, ifc.ifc_buf, oldlen);
251 delete [] ifc.ifc_buf;
252 ifc.ifc_buf = p;
253 }
254 oldlen = ifc.ifc_len;
255 if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0)
256 {
257 lerrno = errno;
258 appliesTo = "ioctl:SIOCGIFCONF";
259 break;
260 }
261 if (ifc.ifc_len == static_cast<int>(sizeof(struct ifreq) * numreqs))
262 {
263 /* assume it overflowed and try again */
264 numreqs += 10;
265 continue;
266 }
267 break;
268 }
269 if (lerrno == 0)
270 {
271 lerrno = ENODEV;
272 appliesTo = "No interfaces found";
273 ifr = ifc.ifc_req;
274 for (n = 0; n < ifc.ifc_len; n += sizeof(struct ifreq))
275 {
276 ifrcopy = *ifr;
277 if (ioctl(sockfd, SIOCGIFFLAGS, &ifrcopy) < 0)
278 {
279 lerrno = errno;
280 appliesTo = "ioctl:SIOCGIFFLAGS";
281 break;
282 }
283#ifdef BLOCXX_GNU_LINUX
284 if ((ifrcopy.ifr_flags & IFF_UP) && !(ifrcopy.ifr_flags & (IFF_LOOPBACK | IFF_DYNAMIC)))
285#else
286 if ((ifrcopy.ifr_flags & IFF_UP))
287#endif
288 {
289 m_name = ifr->ifr_name;
290 lerrno = 0;
291 break;
292 }
293 ifr++;
294 }
295 }
296 if (ifc.ifc_buf != NULL)
297 {
298 delete [] ifc.ifc_buf;
299 }
300 if (lerrno != 0)
301 {
302 BLOCXX_THROW(SocketException, "NwIface::getInterfaceName");
303 }
304}
305
306} // end namespace BLOCXX_NAMESPACE
307
308#endif // #if !defined(BLOCXX_WIN32) && !defined(BLOCXX_NETWARE)
309
#define BLOCXX_THROW(exType, msg)
Throw an exception using FILE and LINE.
unsigned long m_bcastAddr
Definition NwIface.hpp:84
unsigned long getBroadcastAddress()
Definition NwIface.cpp:178
String getBroadcastAddressString()
Definition NwIface.cpp:184
unsigned long getNetmask()
Definition NwIface.cpp:198
void getInterfaceName(SocketHandle_t sockfd)
Definition NwIface.cpp:228
bool sameNetwork(unsigned long addr)
Definition NwIface.cpp:210
static unsigned long stringToAddress(const String &straddr)
Definition NwIface.cpp:222
unsigned long getIPAddress()
Definition NwIface.cpp:166
unsigned long m_netmask
Definition NwIface.hpp:85
This String class is an abstract data type that represents as NULL terminated string of characters.
Definition String.hpp:67
const char * c_str() const
Definition String.cpp:905
String inetAddrToString(UInt64 addr)
Taken from RFC 1321.