1998-10-03 07:41:01 +02:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
*
|
2000-07-06 07:48:31 +02:00
|
|
|
* inet.h
|
|
|
|
* Declarations for operations on INET datatypes.
|
1998-10-03 07:41:01 +02:00
|
|
|
*
|
|
|
|
*
|
2019-01-02 18:44:25 +01:00
|
|
|
* Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
|
2000-01-26 06:58:53 +01:00
|
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
1998-10-03 07:41:01 +02:00
|
|
|
*
|
2010-09-20 22:08:53 +02:00
|
|
|
* src/include/utils/inet.h
|
1998-10-03 07:41:01 +02:00
|
|
|
*
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
2000-08-04 01:07:51 +02:00
|
|
|
#ifndef INET_H
|
|
|
|
#define INET_H
|
1998-10-03 07:41:01 +02:00
|
|
|
|
2006-07-11 15:54:25 +02:00
|
|
|
#include "fmgr.h"
|
|
|
|
|
1998-10-03 07:41:01 +02:00
|
|
|
/*
|
2000-08-04 01:07:51 +02:00
|
|
|
* This is the internal storage format for IP addresses
|
|
|
|
* (both INET and CIDR datatypes):
|
1998-10-03 07:41:01 +02:00
|
|
|
*/
|
|
|
|
typedef struct
|
|
|
|
{
|
2004-06-13 23:57:28 +02:00
|
|
|
unsigned char family; /* PGSQL_AF_INET or PGSQL_AF_INET6 */
|
|
|
|
unsigned char bits; /* number of bits in netmask */
|
|
|
|
unsigned char ipaddr[16]; /* up to 128 bits of address */
|
1999-05-26 00:43:53 +02:00
|
|
|
} inet_struct;
|
1998-10-03 07:41:01 +02:00
|
|
|
|
2003-06-25 00:21:24 +02:00
|
|
|
/*
|
2016-08-23 15:39:54 +02:00
|
|
|
* We use these values for the "family" field.
|
|
|
|
*
|
2003-06-25 00:21:24 +02:00
|
|
|
* Referencing all of the non-AF_INET types to AF_INET lets us work on
|
|
|
|
* machines which may not have the appropriate address family (like
|
|
|
|
* inet6 addresses when AF_INET6 isn't present) but doesn't cause a
|
2016-08-23 15:39:54 +02:00
|
|
|
* dump/reload requirement. Pre-7.4 databases used AF_INET for the family
|
2003-06-25 00:21:24 +02:00
|
|
|
* type on disk.
|
|
|
|
*/
|
|
|
|
#define PGSQL_AF_INET (AF_INET + 0)
|
|
|
|
#define PGSQL_AF_INET6 (AF_INET + 1)
|
|
|
|
|
2000-08-04 01:07:51 +02:00
|
|
|
/*
|
|
|
|
* Both INET and CIDR addresses are represented within Postgres as varlena
|
2007-04-06 06:21:44 +02:00
|
|
|
* objects, ie, there is a varlena header in front of the struct type
|
2014-05-06 18:12:18 +02:00
|
|
|
* depicted above. This struct depicts what we actually have in memory
|
2007-04-06 06:21:44 +02:00
|
|
|
* in "uncompressed" cases. Note that since the maximum data size is only
|
|
|
|
* 18 bytes, INET/CIDR will invariably be stored into tuples using the
|
|
|
|
* 1-byte-header varlena format. However, we have to be prepared to cope
|
|
|
|
* with the 4-byte-header format too, because various code may helpfully
|
|
|
|
* try to "decompress" 1-byte-header datums.
|
2000-08-04 01:07:51 +02:00
|
|
|
*/
|
2007-04-06 06:21:44 +02:00
|
|
|
typedef struct
|
|
|
|
{
|
2008-02-23 20:11:45 +01:00
|
|
|
char vl_len_[4]; /* Do not touch this field directly! */
|
2007-11-15 22:14:46 +01:00
|
|
|
inet_struct inet_data;
|
2007-04-06 06:21:44 +02:00
|
|
|
} inet;
|
1998-10-03 07:41:01 +02:00
|
|
|
|
Add an in-core GiST index opclass for inet/cidr types.
This operator class can accelerate subnet/supernet tests as well as
btree-equivalent ordered comparisons. It also handles a new network
operator inet && inet (overlaps, a/k/a "is supernet or subnet of"),
which is expected to be useful in exclusion constraints.
Ideally this opclass would be the default for GiST with inet/cidr data,
but we can't mark it that way until we figure out how to do a more or
less graceful transition from the current situation, in which the
really-completely-bogus inet/cidr opclasses in contrib/btree_gist are
marked as default. Having the opclass in core and not default is better
than not having it at all, though.
While at it, add new documentation sections to allow us to officially
document GiST/GIN/SP-GiST opclasses, something there was never a clear
place to do before. I filled these in with some simple tables listing
the existing opclasses and the operators they support, but there's
certainly scope to put more information there.
Emre Hasegeli, reviewed by Andreas Karlsson, further hacking by me
2014-04-08 21:46:14 +02:00
|
|
|
/*
|
2014-05-06 18:12:18 +02:00
|
|
|
* Access macros. We use VARDATA_ANY so that we can process short-header
|
Add an in-core GiST index opclass for inet/cidr types.
This operator class can accelerate subnet/supernet tests as well as
btree-equivalent ordered comparisons. It also handles a new network
operator inet && inet (overlaps, a/k/a "is supernet or subnet of"),
which is expected to be useful in exclusion constraints.
Ideally this opclass would be the default for GiST with inet/cidr data,
but we can't mark it that way until we figure out how to do a more or
less graceful transition from the current situation, in which the
really-completely-bogus inet/cidr opclasses in contrib/btree_gist are
marked as default. Having the opclass in core and not default is better
than not having it at all, though.
While at it, add new documentation sections to allow us to officially
document GiST/GIN/SP-GiST opclasses, something there was never a clear
place to do before. I filled these in with some simple tables listing
the existing opclasses and the operators they support, but there's
certainly scope to put more information there.
Emre Hasegeli, reviewed by Andreas Karlsson, further hacking by me
2014-04-08 21:46:14 +02:00
|
|
|
* varlena values without detoasting them. This requires a trick:
|
|
|
|
* VARDATA_ANY assumes the varlena header is already filled in, which is
|
|
|
|
* not the case when constructing a new value (until SET_INET_VARSIZE is
|
|
|
|
* called, which we typically can't do till the end). Therefore, we
|
|
|
|
* always initialize the newly-allocated value to zeroes (using palloc0).
|
|
|
|
* A zero length word will look like the not-1-byte case to VARDATA_ANY,
|
|
|
|
* and so we correctly construct an uncompressed value.
|
|
|
|
*
|
|
|
|
* Note that ip_addrsize(), ip_maxbits(), and SET_INET_VARSIZE() require
|
|
|
|
* the family field to be set correctly.
|
|
|
|
*/
|
|
|
|
#define ip_family(inetptr) \
|
|
|
|
(((inet_struct *) VARDATA_ANY(inetptr))->family)
|
|
|
|
|
|
|
|
#define ip_bits(inetptr) \
|
|
|
|
(((inet_struct *) VARDATA_ANY(inetptr))->bits)
|
|
|
|
|
|
|
|
#define ip_addr(inetptr) \
|
|
|
|
(((inet_struct *) VARDATA_ANY(inetptr))->ipaddr)
|
|
|
|
|
|
|
|
#define ip_addrsize(inetptr) \
|
|
|
|
(ip_family(inetptr) == PGSQL_AF_INET ? 4 : 16)
|
|
|
|
|
|
|
|
#define ip_maxbits(inetptr) \
|
|
|
|
(ip_family(inetptr) == PGSQL_AF_INET ? 32 : 128)
|
|
|
|
|
|
|
|
#define SET_INET_VARSIZE(dst) \
|
|
|
|
SET_VARSIZE(dst, VARHDRSZ + offsetof(inet_struct, ipaddr) + \
|
|
|
|
ip_addrsize(dst))
|
|
|
|
|
2000-08-04 01:07:51 +02:00
|
|
|
|
1998-10-03 07:41:01 +02:00
|
|
|
/*
|
|
|
|
* This is the internal storage format for MAC addresses:
|
|
|
|
*/
|
|
|
|
typedef struct macaddr
|
|
|
|
{
|
|
|
|
unsigned char a;
|
|
|
|
unsigned char b;
|
|
|
|
unsigned char c;
|
|
|
|
unsigned char d;
|
|
|
|
unsigned char e;
|
|
|
|
unsigned char f;
|
1999-05-25 18:15:34 +02:00
|
|
|
} macaddr;
|
1998-10-03 07:41:01 +02:00
|
|
|
|
2017-03-15 16:16:25 +01:00
|
|
|
/*
|
|
|
|
* This is the internal storage format for MAC8 addresses:
|
|
|
|
*/
|
|
|
|
typedef struct macaddr8
|
|
|
|
{
|
|
|
|
unsigned char a;
|
|
|
|
unsigned char b;
|
|
|
|
unsigned char c;
|
|
|
|
unsigned char d;
|
|
|
|
unsigned char e;
|
|
|
|
unsigned char f;
|
|
|
|
unsigned char g;
|
|
|
|
unsigned char h;
|
|
|
|
} macaddr8;
|
|
|
|
|
2000-08-04 01:07:51 +02:00
|
|
|
/*
|
|
|
|
* fmgr interface macros
|
|
|
|
*/
|
2011-11-08 21:39:43 +01:00
|
|
|
#define DatumGetInetPP(X) ((inet *) PG_DETOAST_DATUM_PACKED(X))
|
2001-03-22 05:01:46 +01:00
|
|
|
#define InetPGetDatum(X) PointerGetDatum(X)
|
2011-12-12 08:49:47 +01:00
|
|
|
#define PG_GETARG_INET_PP(n) DatumGetInetPP(PG_GETARG_DATUM(n))
|
2000-08-04 01:07:51 +02:00
|
|
|
#define PG_RETURN_INET_P(x) return InetPGetDatum(x)
|
2017-03-13 00:35:33 +01:00
|
|
|
/* obsolescent variants */
|
|
|
|
#define DatumGetInetP(X) ((inet *) PG_DETOAST_DATUM(X))
|
|
|
|
#define PG_GETARG_INET_P(n) DatumGetInetP(PG_GETARG_DATUM(n))
|
2017-03-15 16:16:25 +01:00
|
|
|
|
2000-08-04 01:07:51 +02:00
|
|
|
/* macaddr is a fixed-length pass-by-reference datatype */
|
|
|
|
#define DatumGetMacaddrP(X) ((macaddr *) DatumGetPointer(X))
|
|
|
|
#define MacaddrPGetDatum(X) PointerGetDatum(X)
|
|
|
|
#define PG_GETARG_MACADDR_P(n) DatumGetMacaddrP(PG_GETARG_DATUM(n))
|
|
|
|
#define PG_RETURN_MACADDR_P(x) return MacaddrPGetDatum(x)
|
|
|
|
|
2017-03-15 16:16:25 +01:00
|
|
|
/* macaddr8 is a fixed-length pass-by-reference datatype */
|
|
|
|
#define DatumGetMacaddr8P(X) ((macaddr8 *) DatumGetPointer(X))
|
|
|
|
#define Macaddr8PGetDatum(X) PointerGetDatum(X)
|
|
|
|
#define PG_GETARG_MACADDR8_P(n) DatumGetMacaddr8P(PG_GETARG_DATUM(n))
|
|
|
|
#define PG_RETURN_MACADDR8_P(x) return Macaddr8PGetDatum(x)
|
|
|
|
|
Add an in-core GiST index opclass for inet/cidr types.
This operator class can accelerate subnet/supernet tests as well as
btree-equivalent ordered comparisons. It also handles a new network
operator inet && inet (overlaps, a/k/a "is supernet or subnet of"),
which is expected to be useful in exclusion constraints.
Ideally this opclass would be the default for GiST with inet/cidr data,
but we can't mark it that way until we figure out how to do a more or
less graceful transition from the current situation, in which the
really-completely-bogus inet/cidr opclasses in contrib/btree_gist are
marked as default. Having the opclass in core and not default is better
than not having it at all, though.
While at it, add new documentation sections to allow us to officially
document GiST/GIN/SP-GiST opclasses, something there was never a clear
place to do before. I filled these in with some simple tables listing
the existing opclasses and the operators they support, but there's
certainly scope to put more information there.
Emre Hasegeli, reviewed by Andreas Karlsson, further hacking by me
2014-04-08 21:46:14 +02:00
|
|
|
/*
|
|
|
|
* Support functions in network.c
|
|
|
|
*/
|
2016-08-23 15:39:54 +02:00
|
|
|
extern inet *cidr_set_masklen_internal(const inet *src, int bits);
|
Add an in-core GiST index opclass for inet/cidr types.
This operator class can accelerate subnet/supernet tests as well as
btree-equivalent ordered comparisons. It also handles a new network
operator inet && inet (overlaps, a/k/a "is supernet or subnet of"),
which is expected to be useful in exclusion constraints.
Ideally this opclass would be the default for GiST with inet/cidr data,
but we can't mark it that way until we figure out how to do a more or
less graceful transition from the current situation, in which the
really-completely-bogus inet/cidr opclasses in contrib/btree_gist are
marked as default. Having the opclass in core and not default is better
than not having it at all, though.
While at it, add new documentation sections to allow us to officially
document GiST/GIN/SP-GiST opclasses, something there was never a clear
place to do before. I filled these in with some simple tables listing
the existing opclasses and the operators they support, but there's
certainly scope to put more information there.
Emre Hasegeli, reviewed by Andreas Karlsson, further hacking by me
2014-04-08 21:46:14 +02:00
|
|
|
extern int bitncmp(const unsigned char *l, const unsigned char *r, int n);
|
|
|
|
extern int bitncommon(const unsigned char *l, const unsigned char *r, int n);
|
|
|
|
|
Phase 2 of pgindent updates.
Change pg_bsd_indent to follow upstream rules for placement of comments
to the right of code, and remove pgindent hack that caused comments
following #endif to not obey the general rule.
Commit e3860ffa4dd0dad0dd9eea4be9cc1412373a8c89 wasn't actually using
the published version of pg_bsd_indent, but a hacked-up version that
tried to minimize the amount of movement of comments to the right of
code. The situation of interest is where such a comment has to be
moved to the right of its default placement at column 33 because there's
code there. BSD indent has always moved right in units of tab stops
in such cases --- but in the previous incarnation, indent was working
in 8-space tab stops, while now it knows we use 4-space tabs. So the
net result is that in about half the cases, such comments are placed
one tab stop left of before. This is better all around: it leaves
more room on the line for comment text, and it means that in such
cases the comment uniformly starts at the next 4-space tab stop after
the code, rather than sometimes one and sometimes two tabs after.
Also, ensure that comments following #endif are indented the same
as comments following other preprocessor commands such as #else.
That inconsistency turns out to have been self-inflicted damage
from a poorly-thought-through post-indent "fixup" in pgindent.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:18:54 +02:00
|
|
|
#endif /* INET_H */
|