1 /*-------------------------------------------------------------------------
2  *
3  * inet.h
4  *	  Declarations for operations on INET datatypes.
5  *
6  *
7  * Portions Copyright (c) 1996-2016, 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  * Referencing all of the non-AF_INET types to AF_INET lets us work on
32  * machines which may not have the appropriate address family (like
33  * inet6 addresses when AF_INET6 isn't present) but doesn't cause a
34  * dump/reload requirement.  Existing databases used AF_INET for the family
35  * type on disk.
36  */
37 #define PGSQL_AF_INET	(AF_INET + 0)
38 #define PGSQL_AF_INET6	(AF_INET + 1)
39 
40 /*
41  * Both INET and CIDR addresses are represented within Postgres as varlena
42  * objects, ie, there is a varlena header in front of the struct type
43  * depicted above.  This struct depicts what we actually have in memory
44  * in "uncompressed" cases.  Note that since the maximum data size is only
45  * 18 bytes, INET/CIDR will invariably be stored into tuples using the
46  * 1-byte-header varlena format.  However, we have to be prepared to cope
47  * with the 4-byte-header format too, because various code may helpfully
48  * try to "decompress" 1-byte-header datums.
49  */
50 typedef struct
51 {
52 	char		vl_len_[4];		/* Do not touch this field directly! */
53 	inet_struct inet_data;
54 } inet;
55 
56 /*
57  *	Access macros.  We use VARDATA_ANY so that we can process short-header
58  *	varlena values without detoasting them.  This requires a trick:
59  *	VARDATA_ANY assumes the varlena header is already filled in, which is
60  *	not the case when constructing a new value (until SET_INET_VARSIZE is
61  *	called, which we typically can't do till the end).  Therefore, we
62  *	always initialize the newly-allocated value to zeroes (using palloc0).
63  *	A zero length word will look like the not-1-byte case to VARDATA_ANY,
64  *	and so we correctly construct an uncompressed value.
65  *
66  *	Note that ip_addrsize(), ip_maxbits(), and SET_INET_VARSIZE() require
67  *	the family field to be set correctly.
68  */
69 #define ip_family(inetptr) \
70 	(((inet_struct *) VARDATA_ANY(inetptr))->family)
71 
72 #define ip_bits(inetptr) \
73 	(((inet_struct *) VARDATA_ANY(inetptr))->bits)
74 
75 #define ip_addr(inetptr) \
76 	(((inet_struct *) VARDATA_ANY(inetptr))->ipaddr)
77 
78 #define ip_addrsize(inetptr) \
79 	(ip_family(inetptr) == PGSQL_AF_INET ? 4 : 16)
80 
81 #define ip_maxbits(inetptr) \
82 	(ip_family(inetptr) == PGSQL_AF_INET ? 32 : 128)
83 
84 #define SET_INET_VARSIZE(dst) \
85 	SET_VARSIZE(dst, VARHDRSZ + offsetof(inet_struct, ipaddr) + \
86 				ip_addrsize(dst))
87 
88 
89 /*
90  *	This is the internal storage format for MAC addresses:
91  */
92 typedef struct macaddr
93 {
94 	unsigned char a;
95 	unsigned char b;
96 	unsigned char c;
97 	unsigned char d;
98 	unsigned char e;
99 	unsigned char f;
100 } macaddr;
101 
102 /*
103  * fmgr interface macros
104  */
105 #define DatumGetInetP(X)	((inet *) PG_DETOAST_DATUM(X))
106 #define DatumGetInetPP(X)	((inet *) PG_DETOAST_DATUM_PACKED(X))
107 #define InetPGetDatum(X)	PointerGetDatum(X)
108 #define PG_GETARG_INET_P(n) DatumGetInetP(PG_GETARG_DATUM(n))
109 #define PG_GETARG_INET_PP(n) DatumGetInetPP(PG_GETARG_DATUM(n))
110 #define PG_RETURN_INET_P(x) return InetPGetDatum(x)
111 /* macaddr is a fixed-length pass-by-reference datatype */
112 #define DatumGetMacaddrP(X)    ((macaddr *) DatumGetPointer(X))
113 #define MacaddrPGetDatum(X)    PointerGetDatum(X)
114 #define PG_GETARG_MACADDR_P(n) DatumGetMacaddrP(PG_GETARG_DATUM(n))
115 #define PG_RETURN_MACADDR_P(x) return MacaddrPGetDatum(x)
116 
117 /*
118  * Support functions in network.c
119  */
120 extern int	bitncmp(const unsigned char *l, const unsigned char *r, int n);
121 extern int	bitncommon(const unsigned char *l, const unsigned char *r, int n);
122 
123 /*
124  * GiST support functions in network_gist.c
125  */
126 extern Datum inet_gist_fetch(PG_FUNCTION_ARGS);
127 extern Datum inet_gist_consistent(PG_FUNCTION_ARGS);
128 extern Datum inet_gist_union(PG_FUNCTION_ARGS);
129 extern Datum inet_gist_compress(PG_FUNCTION_ARGS);
130 extern Datum inet_gist_decompress(PG_FUNCTION_ARGS);
131 extern Datum inet_gist_penalty(PG_FUNCTION_ARGS);
132 extern Datum inet_gist_picksplit(PG_FUNCTION_ARGS);
133 extern Datum inet_gist_same(PG_FUNCTION_ARGS);
134 
135 /*
136  * Estimation functions in network_selfuncs.c
137  */
138 extern Datum networksel(PG_FUNCTION_ARGS);
139 extern Datum networkjoinsel(PG_FUNCTION_ARGS);
140 
141 #endif   /* INET_H */
142