summaryrefslogtreecommitdiffstats
path: root/src/include/utils/inet.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/include/utils/inet.h')
-rw-r--r--src/include/utils/inet.h149
1 files changed, 149 insertions, 0 deletions
diff --git a/src/include/utils/inet.h b/src/include/utils/inet.h
new file mode 100644
index 0000000..f88b075
--- /dev/null
+++ b/src/include/utils/inet.h
@@ -0,0 +1,149 @@
+/*-------------------------------------------------------------------------
+ *
+ * inet.h
+ * Declarations for operations on INET datatypes.
+ *
+ *
+ * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/utils/inet.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef INET_H
+#define INET_H
+
+#include "fmgr.h"
+
+/*
+ * This is the internal storage format for IP addresses
+ * (both INET and CIDR datatypes):
+ */
+typedef struct
+{
+ 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 */
+} inet_struct;
+
+/*
+ * We use these values for the "family" field.
+ *
+ * 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
+ * dump/reload requirement. Pre-7.4 databases used AF_INET for the family
+ * type on disk.
+ */
+#define PGSQL_AF_INET (AF_INET + 0)
+#define PGSQL_AF_INET6 (AF_INET + 1)
+
+/*
+ * Both INET and CIDR addresses are represented within Postgres as varlena
+ * objects, ie, there is a varlena header in front of the struct type
+ * depicted above. This struct depicts what we actually have in memory
+ * 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.
+ */
+typedef struct
+{
+ char vl_len_[4]; /* Do not touch this field directly! */
+ inet_struct inet_data;
+} inet;
+
+/*
+ * Access macros. We use VARDATA_ANY so that we can process short-header
+ * 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))
+
+
+/*
+ * 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;
+} macaddr;
+
+/*
+ * 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;
+
+/*
+ * fmgr interface macros
+ */
+#define DatumGetInetPP(X) ((inet *) PG_DETOAST_DATUM_PACKED(X))
+#define InetPGetDatum(X) PointerGetDatum(X)
+#define PG_GETARG_INET_PP(n) DatumGetInetPP(PG_GETARG_DATUM(n))
+#define PG_RETURN_INET_P(x) return InetPGetDatum(x)
+/* obsolescent variants */
+#define DatumGetInetP(X) ((inet *) PG_DETOAST_DATUM(X))
+#define PG_GETARG_INET_P(n) DatumGetInetP(PG_GETARG_DATUM(n))
+
+/* 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)
+
+/* 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)
+
+/*
+ * Support functions in network.c
+ */
+extern inet *cidr_set_masklen_internal(const inet *src, int bits);
+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);
+
+#endif /* INET_H */