36 #else |
36 #else |
37 # include <winsock2.h> |
37 # include <winsock2.h> |
38 # include <ws2tcpip.h> |
38 # include <ws2tcpip.h> |
39 #endif |
39 #endif |
40 |
40 |
41 #include <stdio.h> |
41 BEGIN_ZFC_NAMESPACE |
42 #include <stdlib.h> |
|
43 #include <string.h> |
|
44 #include <time.h> |
|
45 |
42 |
46 #ifdef _WIN32 |
43 #ifdef _WIN32 |
47 using AddrInfo = ADDRINFOA; |
44 typedef ADDRINFOA AddrInfo; |
48 #else |
45 #else |
49 using AddrInfo = struct addrinfo; |
46 typedef struct addrinfo AddrInfo; |
50 #endif |
47 #endif |
51 |
48 |
52 // ----------------------------------------------------------------------------- |
49 // ----------------------------------------------------------------------------- |
53 // |
50 // |
54 IPAddress::IPAddress() : |
51 IPAddress::IPAddress() : |
67 host (other.host), |
64 host (other.host), |
68 port (other.port) {} |
65 port (other.port) {} |
69 |
66 |
70 // ----------------------------------------------------------------------------- |
67 // ----------------------------------------------------------------------------- |
71 // |
68 // |
72 METHOD |
69 String IPAddress::to_string (WithPort withport) const |
73 IPAddress::to_string (WithPort withport) const -> String |
|
74 { |
70 { |
75 String val; |
71 String val; |
76 |
72 |
77 if (withport == IP_WITH_PORT) |
73 if (withport == WITH_PORT) |
78 val.sprintf ("%u.%u.%u.%u:%u", octet (0), octet (1), octet (2), octet (3), port); |
74 val.sprintf ("%u.%u.%u.%u:%u", octet (0), octet (1), octet (2), octet (3), port); |
79 else |
75 else |
80 val.sprintf ("%u.%u.%u.%u", octet (0), octet (1), octet (2), octet (3)); |
76 val.sprintf ("%u.%u.%u.%u", octet (0), octet (1), octet (2), octet (3)); |
81 |
77 |
82 return val; |
78 return val; |
83 } |
79 } |
84 |
80 |
85 // ----------------------------------------------------------------------------- |
81 // ----------------------------------------------------------------------------- |
86 // |
82 // |
87 METHOD |
83 unsigned char IPAddress::octet (int n) const |
88 IPAddress::octet (int n) const -> unsigned char |
|
89 { |
84 { |
90 return (host >> ((3 - n) * 8)) & 0xFF; |
85 return (host >> ((3 - n) * 8)) & 0xFF; |
91 } |
86 } |
92 |
87 |
93 // ----------------------------------------------------------------------------- |
88 // ----------------------------------------------------------------------------- |
94 // |
89 // |
95 METHOD |
90 void IPAddress::set_octet (int n, unsigned char oct) |
96 IPAddress::set_octet (int n, unsigned char oct) -> void |
|
97 { |
91 { |
98 // TODO: make a big-endian version |
92 // TODO: make a big-endian version |
99 host &= ~(0xFF << (3 - n) * 8); |
93 host &= ~(0xFF << (3 - n) * 8); |
100 host |= oct << ((3 - n) * 8); |
94 host |= oct << ((3 - n) * 8); |
101 } |
95 } |
102 |
96 |
103 // ----------------------------------------------------------------------------- |
97 // ----------------------------------------------------------------------------- |
104 // |
98 // |
105 METHOD |
99 bool IPAddress::compare (const IPAddress& other) const |
106 IPAddress::compare (const IPAddress& other) const -> bool |
|
107 { |
100 { |
108 for (int i = 0; i < 4; ++i) |
101 for (int i = 0; i < 4; ++i) |
109 { |
102 { |
110 if (octet (i) != other.octet (i)) |
103 if (octet (i) != other.octet (i)) |
111 return false; |
104 return false; |
121 return true; |
114 return true; |
122 } |
115 } |
123 |
116 |
124 // ----------------------------------------------------------------------------- |
117 // ----------------------------------------------------------------------------- |
125 // |
118 // |
126 METHOD |
119 bool IPAddress::operator< (const IPAddress& other) const |
127 IPAddress::operator< (const IPAddress& other) const -> bool |
|
128 { |
120 { |
129 for (int i = 0; i < 4; ++i) |
121 for (int i = 0; i < 4; ++i) |
130 { |
122 { |
131 if (octet (i) != other.octet (i)) |
123 if (octet (i) != other.octet (i)) |
132 return octet (i) < other.octet (i); |
124 return octet (i) < other.octet (i); |
135 return port < other.port; |
127 return port < other.port; |
136 } |
128 } |
137 |
129 |
138 // ----------------------------------------------------------------------------- |
130 // ----------------------------------------------------------------------------- |
139 // |
131 // |
140 METHOD |
132 sockaddr_in IPAddress::to_sockaddr_in() const |
141 IPAddress::to_sockaddr_in() const -> sockaddr_in |
|
142 { |
133 { |
143 sockaddr_in claddr; |
134 sockaddr_in claddr; |
144 memset (&claddr, 0, sizeof claddr); |
135 memset (&claddr, 0, sizeof claddr); |
145 claddr.sin_addr.s_addr = htonl (host); |
136 claddr.sin_addr.s_addr = htonl (host); |
146 claddr.sin_port = htons (port); |
137 claddr.sin_port = htons (port); |
148 return claddr; |
139 return claddr; |
149 } |
140 } |
150 |
141 |
151 // ----------------------------------------------------------------------------- |
142 // ----------------------------------------------------------------------------- |
152 // |
143 // |
153 STATIC METHOD |
144 IPAddress IPAddress::from_string (String input) |
154 IPAddress::from_string (String input) -> IPAddress |
|
155 { |
145 { |
156 unsigned int parts[4]; |
146 unsigned int parts[4]; |
157 int colonpos = input.find (":"); |
147 int colonpos = input.find (":"); |
158 String addressString = colonpos == -1 ? input : input.mid (0, colonpos); |
148 String addressString = colonpos == -1 ? input : input.mid (0, colonpos); |
159 IPAddress value; |
149 IPAddress value; |
169 // Possibly a hostname, try resolve it |
159 // Possibly a hostname, try resolve it |
170 value = IPAddress::resolve (addressString); |
160 value = IPAddress::resolve (addressString); |
171 } |
161 } |
172 |
162 |
173 if (colonpos != -1) |
163 if (colonpos != -1) |
174 value.port = input.mid (colonpos + 1, -1).to_int(); |
164 value.port = (unsigned short) input.mid (colonpos + 1, -1).to_int(); |
175 |
165 |
176 return value; |
166 return value; |
177 } |
167 } |
178 |
168 |
179 // ----------------------------------------------------------------------------- |
169 // ----------------------------------------------------------------------------- |
180 // |
170 // |
181 STATIC METHOD |
171 IPAddress IPAddress::resolve (String node) |
182 IPAddress::resolve (String node) -> IPAddress |
|
183 { |
172 { |
184 AddrInfo hints; |
173 AddrInfo hints; |
185 AddrInfo* lookup; |
174 AddrInfo* lookup; |
186 memset (&hints, 0, sizeof hints); |
175 memset (&hints, 0, sizeof hints); |
187 hints.ai_family = AF_INET; |
176 hints.ai_family = AF_INET; |