1/*-------------------------------------------------------------------------
2 *
3 * inet.h
4 * Declarations for operations on INET datatypes.
5 *
6 *
7 * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
8 * Portions Copyright (c) 1994, Regents of the University of California
9 *
10 * src/include/utils/inet.h
11 *
12 *-------------------------------------------------------------------------
13 */
14#ifndef INET_H
15#define INET_H
16
17#include "fmgr.h"
18
19/*
20 * This is the internal storage format for IP addresses
21 * (both INET and CIDR datatypes):
22 */
23typedef struct
24{
25 unsigned char family; /* PGSQL_AF_INET or PGSQL_AF_INET6 */
26 unsigned char bits; /* number of bits in netmask */
27 unsigned char ipaddr[16]; /* up to 128 bits of address */
28} inet_struct;
29
30/*
31 * We use these values for the "family" field.
32 *
33 * Referencing all of the non-AF_INET types to AF_INET lets us work on
34 * machines which may not have the appropriate address family (like
35 * inet6 addresses when AF_INET6 isn't present) but doesn't cause a
36 * dump/reload requirement. Pre-7.4 databases used AF_INET for the family
37 * type on disk.
38 */
39#define PGSQL_AF_INET (AF_INET + 0)
40#define PGSQL_AF_INET6 (AF_INET + 1)
41
42/*
43 * Both INET and CIDR addresses are represented within Postgres as varlena
44 * objects, ie, there is a varlena header in front of the struct type
45 * depicted above. This struct depicts what we actually have in memory
46 * in "uncompressed" cases. Note that since the maximum data size is only
47 * 18 bytes, INET/CIDR will invariably be stored into tuples using the
48 * 1-byte-header varlena format. However, we have to be prepared to cope
49 * with the 4-byte-header format too, because various code may helpfully
50 * try to "decompress" 1-byte-header datums.
51 */
52typedef struct
53{
54 char vl_len_[4]; /* Do not touch this field directly! */
55 inet_struct inet_data;
56} inet;
57
58/*
59 * Access macros. We use VARDATA_ANY so that we can process short-header
60 * varlena values without detoasting them. This requires a trick:
61 * VARDATA_ANY assumes the varlena header is already filled in, which is
62 * not the case when constructing a new value (until SET_INET_VARSIZE is
63 * called, which we typically can't do till the end). Therefore, we
64 * always initialize the newly-allocated value to zeroes (using palloc0).
65 * A zero length word will look like the not-1-byte case to VARDATA_ANY,
66 * and so we correctly construct an uncompressed value.
67 *
68 * Note that ip_addrsize(), ip_maxbits(), and SET_INET_VARSIZE() require
69 * the family field to be set correctly.
70 */
71#define ip_family(inetptr) \
72 (((inet_struct *) VARDATA_ANY(inetptr))->family)
73
74#define ip_bits(inetptr) \
75 (((inet_struct *) VARDATA_ANY(inetptr))->bits)
76
77#define ip_addr(inetptr) \
78 (((inet_struct *) VARDATA_ANY(inetptr))->ipaddr)
79
80#define ip_addrsize(inetptr) \
81 (ip_family(inetptr) == PGSQL_AF_INET ? 4 : 16)
82
83#define ip_maxbits(inetptr) \
84 (ip_family(inetptr) == PGSQL_AF_INET ? 32 : 128)
85
86#define SET_INET_VARSIZE(dst) \
87 SET_VARSIZE(dst, VARHDRSZ + offsetof(inet_struct, ipaddr) + \
88 ip_addrsize(dst))
89
90
91/*
92 * This is the internal storage format for MAC addresses:
93 */
94typedef struct macaddr
95{
96 unsigned char a;
97 unsigned char b;
98 unsigned char c;
99 unsigned char d;
100 unsigned char e;
101 unsigned char f;
102} macaddr;
103
104/*
105 * This is the internal storage format for MAC8 addresses:
106 */
107typedef struct macaddr8
108{
109 unsigned char a;
110 unsigned char b;
111 unsigned char c;
112 unsigned char d;
113 unsigned char e;
114 unsigned char f;
115 unsigned char g;
116 unsigned char h;
117} macaddr8;
118
119/*
120 * fmgr interface macros
121 */
122#define DatumGetInetPP(X) ((inet *) PG_DETOAST_DATUM_PACKED(X))
123#define InetPGetDatum(X) PointerGetDatum(X)
124#define PG_GETARG_INET_PP(n) DatumGetInetPP(PG_GETARG_DATUM(n))
125#define PG_RETURN_INET_P(x) return InetPGetDatum(x)
126/* obsolescent variants */
127#define DatumGetInetP(X) ((inet *) PG_DETOAST_DATUM(X))
128#define PG_GETARG_INET_P(n) DatumGetInetP(PG_GETARG_DATUM(n))
129
130/* macaddr is a fixed-length pass-by-reference datatype */
131#define DatumGetMacaddrP(X) ((macaddr *) DatumGetPointer(X))
132#define MacaddrPGetDatum(X) PointerGetDatum(X)
133#define PG_GETARG_MACADDR_P(n) DatumGetMacaddrP(PG_GETARG_DATUM(n))
134#define PG_RETURN_MACADDR_P(x) return MacaddrPGetDatum(x)
135
136/* macaddr8 is a fixed-length pass-by-reference datatype */
137#define DatumGetMacaddr8P(X) ((macaddr8 *) DatumGetPointer(X))
138#define Macaddr8PGetDatum(X) PointerGetDatum(X)
139#define PG_GETARG_MACADDR8_P(n) DatumGetMacaddr8P(PG_GETARG_DATUM(n))
140#define PG_RETURN_MACADDR8_P(x) return Macaddr8PGetDatum(x)
141
142/*
143 * Support functions in network.c
144 */
145extern inet *cidr_set_masklen_internal(const inet *src, int bits);
146extern int bitncmp(const unsigned char *l, const unsigned char *r, int n);
147extern int bitncommon(const unsigned char *l, const unsigned char *r, int n);
148
149#endif /* INET_H */
150