NCBI C++ ToolKit
ncbi_ifconf.c
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /* $Id: ncbi_ifconf.c 99864 2023-05-17 19:32:48Z saprykin $
2  * ===========================================================================
3  *
4  * PUBLIC DOMAIN NOTICE
5  * National Center for Biotechnology Information
6  *
7  * This software/database is a "United States Government Work" under the
8  * terms of the United States Copyright Act. It was written as part of
9  * the author's official duties as a United States Government employee and
10  * thus cannot be copyrighted. This software/database is freely available
11  * to the public for use. The National Library of Medicine and the U.S.
12  * Government have not placed any restriction on its use or reproduction.
13  *
14  * Although all reasonable efforts have been taken to ensure the accuracy
15  * and reliability of the software and data, the NLM and the U.S.
16  * Government do not and cannot warrant the performance or results that
17  * may be obtained by using this software or data. The NLM and the U.S.
18  * Government disclaim all warranties, express or implied, including
19  * warranties of performance, merchantability or fitness for any particular
20  * purpose.
21  *
22  * Please cite the author in any work or product based on this material.
23  *
24  * ===========================================================================
25  *
26  * Author: Anton Lavrentiev
27  *
28  * File Description:
29  * Get host IP and related network configuration information
30  *
31  * UNIX only!!!
32  *
33  */
34 
35 #include "../ncbi_assert.h"
38 #include <connect/ncbi_socket.h>
39 #include <errno.h>
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include <unistd.h>
44 #include <sys/ioctl.h>
45 #include <sys/socket.h>
46 #ifdef HAVE_SYS_SOCKIO_H
47 # include <sys/sockio.h>
48 #endif /*HAVE_SYS_SOCKIO_H*/
49 #include <net/if.h>
50 
51 
52 #ifdef NCBI_OS_SOLARIS
53 /* Per: man 7 if_tcp */
54 # define ifr_mtu ifr_metric
55 #endif /*NCBI_OS_SOLARIS*/
56 
57 
58 extern int/*bool*/ NcbiGetHostIfConfEx(SNcbiIfConf* c, int s,
59  int flag, unsigned int hint)
60 {
61  unsigned int a, b;
62  struct ifconf ifc;
63  struct ifreq ifr;
64  int/*bool*/ found;
65  size_t size, mtu;
66  char *buf, *p;
67  int n, m;
68 
69  if (!c || s < 0) {
70  errno = EINVAL;
71  return 0;
72  }
73 
74  errno = 0;
75  for (size = 1024; ; size += 1024) {
76  if (!(buf = (char*) calloc(1, size)))
77  return 0;
78 
79  ifc.ifc_len = (int) size;
80  ifc.ifc_buf = buf;
81  if ((n = ioctl(s, SIOCGIFCONF, &ifc)) >= 0
82  && (size_t) ifc.ifc_len + (sizeof(ifr) << 1) < size) {
83  break;
84  }
85 
86  free(buf);
87  if (n < 0 && errno != EINVAL)
88  return 0;
89 
90  if (size > 100000) {
91  errno = E2BIG;
92  return 0;
93  }
94  }
95 
96  mtu = 0;
97  errno = 0;
98  n = m = 0;
99  found = 0/*false*/;
100  a = htonl(INADDR_NONE);
101  b = htonl(INADDR_ANY);
102 
103  if (NcbiIsAPIPA(hint))
104  hint = 0;
105 
106  for (p = buf; p < buf + ifc.ifc_len; p += size) {
107  unsigned int addr, mask;
108 
109  memcpy(&ifr, p, sizeof(ifr));
110 #ifdef _SIZEOF_ADDR_IFREQ
111  size = _SIZEOF_ADDR_IFREQ(ifr);
112 #else
113  size = sizeof(ifr);
114 #endif /*_SIZEOF_ADDR_IFREQ*/
115 
116  if (ioctl(s, SIOCGIFADDR, &ifr) < 0)
117  continue;
118  ++n;
119 
120  if (ifr.ifr_addr.sa_family != AF_INET) {
121  ++m;
122  continue;
123  }
124 
125  addr = ((struct sockaddr_in*) &ifr.ifr_addr)->sin_addr.s_addr;
126 
127  if (addr == htonl(INADDR_NONE) || !addr/*==htonl(INADDR_ANY)*/) {
128  ++m;
129  continue;
130  }
131 
132  if (SOCK_IsLoopbackAddress(addr)) {
133  if (a == htonl(INADDR_NONE))
134  a = addr;
135  continue;
136  }
137  if (ioctl(s, SIOCGIFFLAGS, &ifr) < 0)
138  continue;
139  if ((ifr.ifr_flags & IFF_LOOPBACK) ||
140 #ifdef IFF_PRIVATE
141  (ifr.ifr_flags & IFF_PRIVATE) ||
142 #endif /*IFF_PRIVATE*/
143  !(ifr.ifr_flags & IFF_UP) ||
144  !(ifr.ifr_flags & IFF_RUNNING) ||
145  (flag && !(ifr.ifr_flags & flag))) {
146  continue;
147  }
148  if (ioctl(s, SIOCGIFNETMASK, &ifr) < 0)
149  continue;
150 
151  mask = ((struct sockaddr_in*) &ifr.ifr_addr)->sin_addr.s_addr;
152 
153  if (mask == htonl(INADDR_ANY))
154  continue;
155  if (found) {
156  /* check for duplicates */
157  if (a == addr)
158  b = addr;
159  continue;
160  }
161 
162  a = addr;
163  b = mask;
164 #ifdef SIOCGIFMTU
165  mtu = ioctl(s, SIOCGIFMTU, &ifr) < 0
166  || ifr.ifr_mtu < 0 ? 0 : (size_t) ifr.ifr_mtu;
167 #endif /*SIOCGIFMTU*/
168  if (!NcbiIsAPIPA(addr) && (!hint || hint == addr))
169  found = 1/*true*/;
170  }
171 
172  free(buf);
173 
174  c->address = a;
175  c->netmask = b;
176  c->broadcast = (a == htonl(INADDR_NONE) ||
177  b == htonl(INADDR_ANY) ||
178  a == b ? 0 : (a & b) | ~b);
179  c->nifs = n;
180  c->sifs = m;
181  c->mtu = mtu;
182 
183  return 1;
184 }
185 
186 
187 extern int/*bool*/ NcbiGetHostIfConf(SNcbiIfConf* c)
188 {
189  int s = socket(AF_INET, SOCK_STREAM, 0);
190  if (s != -1) {
191  int retval = NcbiGetHostIfConfEx(c, s, 0, 0);
192  int error = errno;
193  close(s);
194  errno = error;
195  return retval;
196  }
197  return 0/*false*/;
198 }
199 
200 
201 extern char* NcbiGetHostIP(char* buf, size_t bufsize)
202 {
203  char str[32];
204  SNcbiIfConf c;
205  const unsigned char* b = (const unsigned char*) &c.address;
206 
207  assert(buf && bufsize > 0);
208 
209  if ( NcbiGetHostIfConf(&c) ) {
210  verify(sprintf(str, "%u.%u.%u.%u",
211  (unsigned) b[0], (unsigned) b[1],
212  (unsigned) b[2], (unsigned) b[3]) > 0);
213  assert(strlen(str) < sizeof(str));
214  if (strlen(str) < bufsize) {
215  strcpy(buf, str);
216  return buf;
217  }
218  }
219  buf[0] = '\0';
220  return 0;
221 }
ncbi::TMaskedQueryRegions mask
int close(int fd)
Definition: connection.cpp:45
static const char * str(char *buf, int n)
Definition: stats.c:84
int SOCK_IsLoopbackAddress(unsigned int ip)
Check whether an address is a loopback one.
Definition: ncbi_socket.c:8718
unsigned int
A callback function used to compare two keys in a database.
Definition: types.hpp:1210
char * buf
if(yy_accept[yy_current_state])
yy_size_t n
const struct ncbi::grid::netcache::search::fields::SIZE size
#define verify(expr)
Definition: ncbi_assert.h:51
int NcbiGetHostIfConfEx(SNcbiIfConf *c, int s, int flag, unsigned int hint)
Definition: ncbi_ifconf.c:58
int NcbiGetHostIfConf(SNcbiIfConf *c)
Definition: ncbi_ifconf.c:187
char * NcbiGetHostIP(char *buf, size_t bufsize)
Definition: ncbi_ifconf.c:201
#define INADDR_NONE
Definition: ncbi_ifconf.h:47
#define INADDR_ANY
Definition: ncbi_ifconf.h:50
unsigned int a
Definition: ncbi_localip.c:102
int NcbiIsAPIPA(unsigned int ip)
Return non-zero (true) if the IP address (in network byte order) provided as an agrument,...
static int bufsize
Definition: pcregrep.c:162
#define assert(x)
Definition: srv_diag.hpp:58
unsigned int netmask
Definition: ncbi_ifconf.h:61
size_t mtu
Definition: ncbi_ifconf.h:65
unsigned int address
Definition: ncbi_ifconf.h:60
unsigned int broadcast
Definition: ncbi_ifconf.h:62
void free(voidpf ptr)
voidp calloc(uInt items, uInt size)
Modified on Sun Jul 14 04:58:11 2024 by modify_doxy.py rev. 669887