1 /* ipr.h */
2 #ifndef IPR_H
3 #define IPR_H
4 
5 #include <string.h>
6 #include <sys/socket.h>
7 
8 #include "fmgr.h"
9 
10 #include "utils/inet.h"
11 #include "utils/palloc.h"
12 
13 #if !defined(PG_VERSION_NUM)
14 #error "Unknown or unsupported postgresql version"
15 #endif
16 #if PG_VERSION_NUM < 80400
17 #error "Unknown or unsupported postgresql version"
18 #endif
19 
20 #ifndef PGDLLEXPORT
21 #define PGDLLEXPORT
22 #endif
23 
24 PGDLLEXPORT bool ip4_raw_input(const char *src, uint32 *dst);
25 PGDLLEXPORT bool ip6_raw_input(const char *src, uint64 *dst);
26 PGDLLEXPORT int ip4_raw_output(uint32 ip, char *str, int len);
27 PGDLLEXPORT int ip6_raw_output(uint64 *ip, char *str, int len);
28 
29 /* IP4 = uint32, stored in host-order. fixed-length and pass by value. */
30 typedef uint32 IP4;
31 
32 #define IP4_INITIALIZER 0
33 
34 /* IP4R = range of IP4, stored in host-order. fixed-length by reference */
35 typedef struct IP4R {
36     IP4 lower;
37     IP4 upper;
38 } IP4R;
39 
40 #define IP4R_INITIALIZER {0,0}
41 
42 /*
43  * IP6 = 2 x uint64, stored hi to lo, each stored in host-order.
44  * fixed-length and pass by reference.
45  */
46 typedef struct IP6 {
47     uint64 bits[2];
48 } IP6;
49 
50 #define IP6_INITIALIZER {{0,0}}
51 
52 /* IP6R = range of IP6. fixed-length by reference */
53 typedef struct IP6R {
54     IP6 lower;
55     IP6 upper;
56 } IP6R;
57 
58 #define IP6R_INITIALIZER {IP6_INITIALIZER,IP6_INITIALIZER}
59 
60 #define IP6_STRING_MAX (sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")+2)
61 #define IP6R_STRING_MAX (2*IP6_STRING_MAX)
62 
63 #define IP4_STRING_MAX (sizeof("255.255.255.255"))
64 #define IP4R_STRING_MAX (2*IP4_STRING_MAX)
65 
66 typedef union IP {
67 	IP6 ip6;
68 	IP4 ip4;
69 } IP;
70 
71 #define IP_INITIALIZER {IP6_INITIALIZER}
72 
73 #define ipr_af_maxbits(af_) ((af_) == PGSQL_AF_INET ? 32 : 128)
74 #define ip_sizeof(af_) ((af_) == PGSQL_AF_INET ? sizeof(IP4) : sizeof(IP6))
75 #define ipr_sizeof(af_) ((af_) == PGSQL_AF_INET ? sizeof(IP4R) : sizeof(IP6R))
76 
77 typedef void *IP_P;  /* unaligned! */
78 
79 PGDLLEXPORT void ipaddr_internal_error(void) __attribute__((noreturn));
80 
81 static inline
ip_unpack(IP_P in,IP * out)82 int ip_unpack(IP_P in, IP *out)
83 {
84     switch (VARSIZE_ANY_EXHDR(in))
85     {
86         case sizeof(IP4):
87             memcpy(&out->ip4, VARDATA_ANY(in), sizeof(IP4));
88             return PGSQL_AF_INET;
89         case sizeof(IP6):
90             memcpy(&out->ip6, VARDATA_ANY(in), sizeof(IP6));
91             return PGSQL_AF_INET6;
92         default:
93 			ipaddr_internal_error();
94     }
95 }
96 
97 static inline
ip_pack(int af,IP * val)98 IP_P ip_pack(int af, IP *val)
99 {
100 	int sz = ip_sizeof(af);
101     IP_P out = palloc(VARHDRSZ + sz);
102 
103 	SET_VARSIZE(out, VARHDRSZ + sz);
104 	memcpy(VARDATA(out), val, sz);
105 	return out;
106 }
107 
108 typedef union IPR {
109 	IP6R ip6r;
110 	IP4R ip4r;
111 } IPR;
112 
113 #define IPR_INITIALIZER {IP6R_INITIALIZER}
114 
115 typedef void *IPR_P;  /* unaligned! */
116 
117 PGDLLEXPORT int ipr_unpack(IPR_P in, IPR *out);
118 PGDLLEXPORT IPR_P ipr_pack(int af, IPR *val);
119 
120 #define DatumGetIP4RP(X)	((IP4R *) DatumGetPointer(X))
121 #define IP4RPGetDatum(X)	PointerGetDatum(X)
122 #define PG_GETARG_IP4R_P(n) DatumGetIP4RP(PG_GETARG_DATUM(n))
123 #define PG_RETURN_IP4R_P(x) return IP4RPGetDatum(x)
124 
125 #define DatumGetIP4(X) DatumGetUInt32(X)
126 #define IP4GetDatum(X) UInt32GetDatum(X)
127 #define PG_GETARG_IP4(n) PG_GETARG_UINT32(n)
128 #define PG_RETURN_IP4(x) PG_RETURN_UINT32(x)
129 
130 #define DatumGetIP6RP(X)	((IP6R *) DatumGetPointer(X))
131 #define IP6RPGetDatum(X)	PointerGetDatum(X)
132 #define PG_GETARG_IP6R_P(n) DatumGetIP6RP(PG_GETARG_DATUM(n))
133 #define PG_RETURN_IP6R_P(x) return IP6RPGetDatum(x)
134 
135 #define DatumGetIP6P(X)	((IP6 *) DatumGetPointer(X))
136 #define IP6PGetDatum(X)	PointerGetDatum(X)
137 #define PG_GETARG_IP6_P(n) DatumGetIP6P(PG_GETARG_DATUM(n))
138 #define PG_RETURN_IP6_P(x) return IP6PGetDatum(x)
139 
140 #define DatumGetIP_P(X) ((IP_P) PG_DETOAST_DATUM_PACKED(X))
141 #define IP_PGetDatum(X) PointerGetDatum(X)
142 #define PG_GETARG_IP_P(n) DatumGetIP_P(PG_GETARG_DATUM(n))
143 #define PG_RETURN_IP_P(x) return IP_PGetDatum(x)
144 
145 #define DatumGetIPR_P(X) ((IP_P) PG_DETOAST_DATUM_PACKED(X))
146 #define IPR_PGetDatum(X) PointerGetDatum(X)
147 #define PG_GETARG_IPR_P(n) DatumGetIPR_P(PG_GETARG_DATUM(n))
148 #define PG_RETURN_IPR_P(x) return IPR_PGetDatum(x)
149 
150 #endif
151 /* end */
152