Age Owner TLA Line data Source code
1 : /*-------------------------------------------------------------------------
2 : *
3 : * inet.h
4 : * Declarations for operations on INET datatypes.
5 : *
6 : *
7 : * Portions Copyright (c) 1996-2023, 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 : */
23 : typedef 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 did not have the appropriate address family (like
35 : * inet6 addresses when AF_INET6 wasn't present) but didn'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 : */
52 : typedef 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 : */
94 : typedef 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 : */
107 : typedef 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 : static inline inet *
194 peter 123 GNC 566512 : DatumGetInetPP(Datum X)
124 : {
125 566512 : return (inet *) PG_DETOAST_DATUM_PACKED(X);
126 : }
127 :
128 : static inline Datum
129 8079 : InetPGetDatum(const inet *X)
130 : {
131 8079 : return PointerGetDatum(X);
132 : }
133 :
134 : #define PG_GETARG_INET_PP(n) DatumGetInetPP(PG_GETARG_DATUM(n))
8284 tgl 135 ECB : #define PG_RETURN_INET_P(x) return InetPGetDatum(x)
136 :
137 : /* obsolescent variants */
138 : static inline inet *
139 : DatumGetInetP(Datum X)
140 : {
141 : return (inet *) PG_DETOAST_DATUM(X);
142 : }
143 : #define PG_GETARG_INET_P(n) DatumGetInetP(PG_GETARG_DATUM(n))
2216 sfrost 144 :
145 : /* macaddr is a fixed-length pass-by-reference datatype */
146 : static inline macaddr *
194 peter 147 GNC 208171 : DatumGetMacaddrP(Datum X)
148 : {
149 208171 : return (macaddr *) DatumGetPointer(X);
150 : }
151 :
152 : static inline Datum
153 15198 : MacaddrPGetDatum(const macaddr *X)
154 : {
155 15198 : return PointerGetDatum(X);
156 : }
157 :
158 : #define PG_GETARG_MACADDR_P(n) DatumGetMacaddrP(PG_GETARG_DATUM(n))
159 : #define PG_RETURN_MACADDR_P(x) return MacaddrPGetDatum(x)
160 :
161 : /* macaddr8 is a fixed-length pass-by-reference datatype */
162 : static inline macaddr8 *
163 181087 : DatumGetMacaddr8P(Datum X)
164 : {
165 181087 : return (macaddr8 *) DatumGetPointer(X);
166 : }
167 :
168 : static inline Datum
169 14593 : Macaddr8PGetDatum(const macaddr8 *X)
170 : {
171 14593 : return PointerGetDatum(X);
172 : }
173 :
174 : #define PG_GETARG_MACADDR8_P(n) DatumGetMacaddr8P(PG_GETARG_DATUM(n))
175 : #define PG_RETURN_MACADDR8_P(x) return Macaddr8PGetDatum(x)
176 :
177 : /*
178 : * Support functions in network.c
179 : */
180 : extern inet *cidr_set_masklen_internal(const inet *src, int bits);
181 : extern int bitncmp(const unsigned char *l, const unsigned char *r, int n);
3288 tgl 182 ECB : extern int bitncommon(const unsigned char *l, const unsigned char *r, int n);
183 :
2118 184 : #endif /* INET_H */
|