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 * 123 461734 : DatumGetInetPP(Datum X) 124 : { 125 461734 : return (inet *) PG_DETOAST_DATUM_PACKED(X); 126 : } 127 : 128 : static inline Datum 129 16220 : InetPGetDatum(const inet *X) 130 : { 131 16220 : 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 130742 : DatumGetMacaddrP(Datum X) 148 : { 149 130742 : return (macaddr *) DatumGetPointer(X); 150 : } 151 : 152 : static inline Datum 153 30396 : MacaddrPGetDatum(const macaddr *X) 154 : { 155 30396 : 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 104294 : DatumGetMacaddr8P(Datum X) 164 : { 165 104294 : return (macaddr8 *) DatumGetPointer(X); 166 : } 167 : 168 : static inline Datum 169 29186 : Macaddr8PGetDatum(const macaddr8 *X) 170 : { 171 29186 : 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 */