Age Owner Branch data TLA Line data Source code
1 : : /*-------------------------------------------------------------------------
2 : : *
3 : : * inet.h
4 : : * Declarations for operations on INET datatypes.
5 : : *
6 : : *
7 : : * Portions Copyright (c) 1996-2024, 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 *
565 peter@eisentraut.org 123 :CBC 589990 : DatumGetInetPP(Datum X)
124 : : {
125 : 589990 : return (inet *) PG_DETOAST_DATUM_PACKED(X);
126 : : }
127 : :
128 : : static inline Datum
129 : 8605 : InetPGetDatum(const inet *X)
130 : : {
131 : 8605 : return PointerGetDatum(X);
132 : : }
133 : :
134 : : #define PG_GETARG_INET_PP(n) DatumGetInetPP(PG_GETARG_DATUM(n))
135 : : #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))
144 : :
145 : : /* macaddr is a fixed-length pass-by-reference datatype */
146 : : static inline macaddr *
147 : 216737 : DatumGetMacaddrP(Datum X)
148 : : {
149 : 216737 : 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 : 185679 : DatumGetMacaddr8P(Datum X)
164 : : {
165 : 185679 : 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);
182 : : extern int bitncommon(const unsigned char *l, const unsigned char *r, int n);
183 : :
184 : : #endif /* INET_H */
|