1 /*------------------------------------------------------------------------- 2 * 3 * inet.h 4 * Declarations for operations on INET datatypes. 5 * 6 * 7 * Portions Copyright (c) 1996-2017, 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