PostgreSQL Source Code  git master
ifaddr.c File Reference
#include "postgres.h"
#include <unistd.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <sys/file.h>
#include "libpq/ifaddr.h"
#include "port/pg_bswap.h"
#include <sys/ioctl.h>
#include <net/if.h>
Include dependency graph for ifaddr.c:

Go to the source code of this file.

Functions

static int range_sockaddr_AF_INET (const struct sockaddr_in *addr, const struct sockaddr_in *netaddr, const struct sockaddr_in *netmask)
 
static int range_sockaddr_AF_INET6 (const struct sockaddr_in6 *addr, const struct sockaddr_in6 *netaddr, const struct sockaddr_in6 *netmask)
 
int pg_range_sockaddr (const struct sockaddr_storage *addr, const struct sockaddr_storage *netaddr, const struct sockaddr_storage *netmask)
 
int pg_sockaddr_cidr_mask (struct sockaddr_storage *mask, char *numbits, int family)
 
static void run_ifaddr_callback (PgIfAddrCallback callback, void *cb_data, struct sockaddr *addr, struct sockaddr *mask)
 
int pg_foreach_ifaddr (PgIfAddrCallback callback, void *cb_data)
 

Function Documentation

◆ pg_foreach_ifaddr()

int pg_foreach_ifaddr ( PgIfAddrCallback  callback,
void *  cb_data 
)

Definition at line 425 of file ifaddr.c.

426 {
427  struct sockaddr_in addr;
428  struct sockaddr_storage mask;
429  struct sockaddr_in6 addr6;
430 
431  /* addr 127.0.0.1/8 */
432  memset(&addr, 0, sizeof(addr));
433  addr.sin_family = AF_INET;
434  addr.sin_addr.s_addr = pg_ntoh32(0x7f000001);
435  memset(&mask, 0, sizeof(mask));
436  pg_sockaddr_cidr_mask(&mask, "8", AF_INET);
437  run_ifaddr_callback(callback, cb_data,
438  (struct sockaddr *) &addr,
439  (struct sockaddr *) &mask);
440 
441  /* addr ::1/128 */
442  memset(&addr6, 0, sizeof(addr6));
443  addr6.sin6_family = AF_INET6;
444  addr6.sin6_addr.s6_addr[15] = 1;
445  memset(&mask, 0, sizeof(mask));
446  pg_sockaddr_cidr_mask(&mask, "128", AF_INET6);
447  run_ifaddr_callback(callback, cb_data,
448  (struct sockaddr *) &addr6,
449  (struct sockaddr *) &mask);
450 
451  return 0;
452 }
int pg_sockaddr_cidr_mask(struct sockaddr_storage *mask, char *numbits, int family)
Definition: ifaddr.c:105
static void run_ifaddr_callback(PgIfAddrCallback callback, void *cb_data, struct sockaddr *addr, struct sockaddr *mask)
Definition: ifaddr.c:181
#define pg_ntoh32(x)
Definition: pg_bswap.h:125
static void callback(struct sockaddr *addr, struct sockaddr *mask, void *unused)
Definition: test_ifaddrs.c:46

References callback(), pg_ntoh32, pg_sockaddr_cidr_mask(), and run_ifaddr_callback().

Referenced by check_same_host_or_net(), and main().

◆ pg_range_sockaddr()

int pg_range_sockaddr ( const struct sockaddr_storage *  addr,
const struct sockaddr_storage *  netaddr,
const struct sockaddr_storage *  netmask 
)

Definition at line 49 of file ifaddr.c.

52 {
53  if (addr->ss_family == AF_INET)
54  return range_sockaddr_AF_INET((const struct sockaddr_in *) addr,
55  (const struct sockaddr_in *) netaddr,
56  (const struct sockaddr_in *) netmask);
57  else if (addr->ss_family == AF_INET6)
58  return range_sockaddr_AF_INET6((const struct sockaddr_in6 *) addr,
59  (const struct sockaddr_in6 *) netaddr,
60  (const struct sockaddr_in6 *) netmask);
61  else
62  return 0;
63 }
static int range_sockaddr_AF_INET6(const struct sockaddr_in6 *addr, const struct sockaddr_in6 *netaddr, const struct sockaddr_in6 *netmask)
Definition: ifaddr.c:78
static int range_sockaddr_AF_INET(const struct sockaddr_in *addr, const struct sockaddr_in *netaddr, const struct sockaddr_in *netmask)
Definition: ifaddr.c:66

References range_sockaddr_AF_INET(), and range_sockaddr_AF_INET6().

Referenced by check_ip().

◆ pg_sockaddr_cidr_mask()

int pg_sockaddr_cidr_mask ( struct sockaddr_storage *  mask,
char *  numbits,
int  family 
)

Definition at line 105 of file ifaddr.c.

106 {
107  long bits;
108  char *endptr;
109 
110  if (numbits == NULL)
111  {
112  bits = (family == AF_INET) ? 32 : 128;
113  }
114  else
115  {
116  bits = strtol(numbits, &endptr, 10);
117  if (*numbits == '\0' || *endptr != '\0')
118  return -1;
119  }
120 
121  switch (family)
122  {
123  case AF_INET:
124  {
125  struct sockaddr_in mask4;
126  long maskl;
127 
128  if (bits < 0 || bits > 32)
129  return -1;
130  memset(&mask4, 0, sizeof(mask4));
131  /* avoid "x << 32", which is not portable */
132  if (bits > 0)
133  maskl = (0xffffffffUL << (32 - (int) bits))
134  & 0xffffffffUL;
135  else
136  maskl = 0;
137  mask4.sin_addr.s_addr = pg_hton32(maskl);
138  memcpy(mask, &mask4, sizeof(mask4));
139  break;
140  }
141 
142  case AF_INET6:
143  {
144  struct sockaddr_in6 mask6;
145  int i;
146 
147  if (bits < 0 || bits > 128)
148  return -1;
149  memset(&mask6, 0, sizeof(mask6));
150  for (i = 0; i < 16; i++)
151  {
152  if (bits <= 0)
153  mask6.sin6_addr.s6_addr[i] = 0;
154  else if (bits >= 8)
155  mask6.sin6_addr.s6_addr[i] = 0xff;
156  else
157  {
158  mask6.sin6_addr.s6_addr[i] =
159  (0xff << (8 - (int) bits)) & 0xff;
160  }
161  bits -= 8;
162  }
163  memcpy(mask, &mask6, sizeof(mask6));
164  break;
165  }
166 
167  default:
168  return -1;
169  }
170 
171  mask->ss_family = family;
172  return 0;
173 }
int i
Definition: isn.c:72
#define pg_hton32(x)
Definition: pg_bswap.h:121

References i, and pg_hton32.

Referenced by check_network_callback(), parse_hba_line(), pg_foreach_ifaddr(), and run_ifaddr_callback().

◆ range_sockaddr_AF_INET()

static int range_sockaddr_AF_INET ( const struct sockaddr_in *  addr,
const struct sockaddr_in *  netaddr,
const struct sockaddr_in *  netmask 
)
static

Definition at line 66 of file ifaddr.c.

69 {
70  if (((addr->sin_addr.s_addr ^ netaddr->sin_addr.s_addr) &
71  netmask->sin_addr.s_addr) == 0)
72  return 1;
73  else
74  return 0;
75 }

Referenced by pg_range_sockaddr().

◆ range_sockaddr_AF_INET6()

static int range_sockaddr_AF_INET6 ( const struct sockaddr_in6 *  addr,
const struct sockaddr_in6 *  netaddr,
const struct sockaddr_in6 *  netmask 
)
static

Definition at line 78 of file ifaddr.c.

81 {
82  int i;
83 
84  for (i = 0; i < 16; i++)
85  {
86  if (((addr->sin6_addr.s6_addr[i] ^ netaddr->sin6_addr.s6_addr[i]) &
87  netmask->sin6_addr.s6_addr[i]) != 0)
88  return 0;
89  }
90 
91  return 1;
92 }

References i.

Referenced by pg_range_sockaddr().

◆ run_ifaddr_callback()

static void run_ifaddr_callback ( PgIfAddrCallback  callback,
void *  cb_data,
struct sockaddr *  addr,
struct sockaddr *  mask 
)
static

Definition at line 181 of file ifaddr.c.

183 {
184  struct sockaddr_storage fullmask;
185 
186  if (!addr)
187  return;
188 
189  /* Check that the mask is valid */
190  if (mask)
191  {
192  if (mask->sa_family != addr->sa_family)
193  {
194  mask = NULL;
195  }
196  else if (mask->sa_family == AF_INET)
197  {
198  if (((struct sockaddr_in *) mask)->sin_addr.s_addr == INADDR_ANY)
199  mask = NULL;
200  }
201  else if (mask->sa_family == AF_INET6)
202  {
203  if (IN6_IS_ADDR_UNSPECIFIED(&((struct sockaddr_in6 *) mask)->sin6_addr))
204  mask = NULL;
205  }
206  }
207 
208  /* If mask is invalid, generate our own fully-set mask */
209  if (!mask)
210  {
211  pg_sockaddr_cidr_mask(&fullmask, NULL, addr->sa_family);
212  mask = (struct sockaddr *) &fullmask;
213  }
214 
215  (*callback) (addr, mask, cb_data);
216 }

References pg_sockaddr_cidr_mask().

Referenced by pg_foreach_ifaddr().