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 | */ |
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 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 | */ |
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 | #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 | */ |
145 | extern inet *cidr_set_masklen_internal(const inet *src, int bits); |
146 | extern int bitncmp(const unsigned char *l, const unsigned char *r, int n); |
147 | extern int bitncommon(const unsigned char *l, const unsigned char *r, int n); |
148 | |
149 | #endif /* INET_H */ |
150 | |