1
+ #pragma once
2
+
3
+ #include < sockaddrin.h>
4
+ #include < map>
5
+ #include < variant>
6
+
7
+ struct FakeAddrPool {
8
+
9
+ struct IPv4Addr {
10
+ in_addr addr;
11
+
12
+ IPv4Addr () { memset (&this ->addr , 0 , sizeof (in_addr)); }
13
+
14
+ IPv4Addr (const in_addr &addr) : addr(addr) {}
15
+
16
+ IPv4Addr (ULONG addr) { this ->addr .s_addr = addr; }
17
+
18
+ bool operator <(const IPv4Addr &other) const {
19
+ return memcmp (&addr, &other.addr , sizeof (in_addr)) < 0 ;
20
+ }
21
+
22
+ bool operator ==(const IPv4Addr &other) const {
23
+ return memcmp (&addr, &other.addr , sizeof (in_addr)) == 0 ;
24
+ }
25
+ };
26
+
27
+ struct IPv6Addr {
28
+ in6_addr addr;
29
+
30
+ IPv6Addr () { memset (&addr, 0 , sizeof (in6_addr)); }
31
+
32
+ IPv6Addr (const in6_addr &addr) : addr(addr) {}
33
+
34
+ bool operator <(const IPv6Addr &other) const {
35
+ return memcmp (&addr, &other.addr , sizeof (in6_addr)) < 0 ;
36
+ }
37
+
38
+ bool operator ==(const IPv6Addr &other) const {
39
+ return memcmp (&addr, &other.addr , sizeof (in6_addr)) == 0 ;
40
+ }
41
+ };
42
+
43
+ struct IPAddr {
44
+ short family;
45
+ std::variant<IPv4Addr, IPv6Addr> ip;
46
+
47
+ IPAddr () : family(AF_INET), ip(IPv4Addr()) {}
48
+ IPAddr (const in_addr &addr) : family(AF_INET), ip(IPv4Addr(addr)) {}
49
+ IPAddr (const IPv4Addr &addr) : family(AF_INET), ip(addr) {}
50
+ IPAddr (const in6_addr &addr) : family(AF_INET6), ip(IPv6Addr(addr)) {}
51
+ IPAddr (const IPv6Addr &addr) : family(AF_INET6), ip(addr) {}
52
+
53
+ bool operator <(const IPAddr &other) const {
54
+ if (family != other.family ) {
55
+ return family < other.family ;
56
+ }
57
+ if (family == AF_INET) {
58
+ return std::get<IPv4Addr>(ip) < std::get<IPv4Addr>(other.ip );
59
+ }
60
+ return std::get<IPv6Addr>(ip) < std::get<IPv6Addr>(other.ip );
61
+ }
62
+
63
+ bool operator ==(const IPAddr &other) const {
64
+ if (family != other.family ) {
65
+ return false ;
66
+ }
67
+ if (family == AF_INET) {
68
+ return std::get<IPv4Addr>(ip) == std::get<IPv4Addr>(other.ip );
69
+ }
70
+ return std::get<IPv6Addr>(ip) == std::get<IPv6Addr>(other.ip );
71
+ }
72
+ };
73
+
74
+ std::map<IPv4Addr, IPAddr> fake_to_real;
75
+ std::map<IPAddr, IPv4Addr> real_to_fake;
76
+ in_addr start;
77
+ in_addr end;
78
+ in_addr current;
79
+
80
+ FakeAddrPool (in_addr start, u_long range) {
81
+ this ->start = start;
82
+ this ->end = next (start, range);
83
+ this ->current = start;
84
+ }
85
+
86
+ sockaddr_in get_fake_addr (const SockAddrIn &addr) {
87
+ switch (addr.get_family ()) {
88
+ case AF_INET:
89
+ return get_fake_addr (IPv4Addr (addr.addr .addr_v4 .sin_addr ));
90
+ case AF_INET6:
91
+ return get_fake_addr (IPv6Addr (addr.addr .addr_v6 .sin6_addr ));
92
+ default :
93
+ sockaddr_in fake_addr;
94
+ memset (&fake_addr, 0 , sizeof (fake_addr));
95
+ return fake_addr;
96
+ }
97
+ }
98
+
99
+ sockaddr_in get_fake_addr (const sockaddr_in6 *addr) {
100
+ return get_fake_addr (IPv6Addr (addr->sin6_addr ));
101
+ }
102
+
103
+ sockaddr_in get_fake_addr (const sockaddr_in *addr) {
104
+ return get_fake_addr (IPv4Addr (addr->sin_addr ));
105
+ }
106
+
107
+ sockaddr_in get_fake_addr (const IPAddr &addr) {
108
+ in_addr fake_ip;
109
+ if (real_to_fake.count (addr)) {
110
+ fake_ip = real_to_fake[addr].addr ;
111
+ } else {
112
+ fake_ip = search_available_addr (current);
113
+ IPv4Addr addr4 (fake_ip);
114
+ real_to_fake[addr] = addr4;
115
+ fake_to_real[addr4] = addr;
116
+ }
117
+ sockaddr_in fake_addr;
118
+ memset (&fake_addr, 0 , sizeof (fake_addr));
119
+ fake_addr.sin_family = AF_INET;
120
+ fake_addr.sin_addr = fake_ip;
121
+ return fake_addr;
122
+ }
123
+
124
+ SockAddrIn get_origin_addr (const sockaddr_in *addr) {
125
+ SockAddrIn origin_addr;
126
+ IPv4Addr addr4 (addr->sin_addr );
127
+ if (fake_to_real.count (addr4)) {
128
+ IPAddr addr = fake_to_real[addr4];
129
+ switch (addr.family ) {
130
+ case AF_INET:
131
+ origin_addr.addr .addr_v4 .sin_family = AF_INET;
132
+ origin_addr.addr .addr_v4 .sin_addr = std::get<IPv4Addr>(addr.ip ).addr ;
133
+ break ;
134
+ case AF_INET6:
135
+ origin_addr.addr .addr_v6 .sin6_family = AF_INET6;
136
+ origin_addr.addr .addr_v6 .sin6_addr = std::get<IPv6Addr>(addr.ip ).addr ;
137
+ break ;
138
+ }
139
+ }
140
+ return origin_addr;
141
+ }
142
+
143
+ bool has_origin_addr (const sockaddr_in *addr) {
144
+ return fake_to_real.count (IPv4Addr (addr->sin_addr ));
145
+ }
146
+
147
+ in_addr search_available_addr (in_addr search_start) {
148
+ if (!fake_to_real.count (IPv4Addr (search_start))) {
149
+ return search_start;
150
+ }
151
+ in_addr addr = next (search_start);
152
+ while (memcmp (&addr, &search_start, sizeof (in_addr)) != 0 ) {
153
+ if (!fake_to_real.count (IPv4Addr (addr))) {
154
+ return addr;
155
+ }
156
+ addr = next (addr);
157
+ if (memcmp (&addr, &search_start, sizeof (in_addr)) == 0 ) {
158
+ addr = start;
159
+ }
160
+ }
161
+ return search_start;
162
+ }
163
+
164
+ in_addr next (const in_addr &addr, int step = 1 ) {
165
+ ULONG hl = (ULONG)addr.S_un .S_un_b .s_b1 << 24 |
166
+ (ULONG)addr.S_un .S_un_b .s_b2 << 16 |
167
+ (ULONG)addr.S_un .S_un_b .s_b3 << 8 |
168
+ (ULONG)addr.S_un .S_un_b .s_b4 ;
169
+ hl += step;
170
+ in_addr next_addr;
171
+ next_addr.S_un .S_un_b .s_b1 = (unsigned char )(hl >> 24 );
172
+ next_addr.S_un .S_un_b .s_b2 = (unsigned char )(hl >> 16 );
173
+ next_addr.S_un .S_un_b .s_b3 = (unsigned char )(hl >> 8 );
174
+ next_addr.S_un .S_un_b .s_b4 = (unsigned char )hl;
175
+ return next_addr;
176
+ }
177
+ };
0 commit comments