Thu, 11 Dec 2014 07:18:11 +0200
- added huffman lib, now capable of initializing an rcon connection!
5 | 1 | #include <stdio.h> |
2 | #include <stdlib.h> | |
3 | #include <string.h> | |
4 | #include <time.h> | |
5 | #include <netinet/in.h> | |
6 | #include <netdb.h> | |
7 | #include "ipaddress.h" | |
8 | ||
9 | bool IPAddress::sink; | |
10 | ||
11 | // ----------------------------------------------------------------------------- | |
12 | // | |
13 | IPAddress::IPAddress() : | |
14 | host (0), | |
15 | port (0) {} | |
16 | ||
17 | // ----------------------------------------------------------------------------- | |
18 | // | |
19 | IPAddress::IPAddress (unsigned long host, unsigned short port) : | |
20 | host (host), | |
21 | port (port) {} | |
22 | ||
23 | // ----------------------------------------------------------------------------- | |
24 | // | |
25 | IPAddress::IPAddress (const IPAddress& other) : | |
26 | host (other.host), | |
27 | port (other.port) {} | |
28 | ||
29 | // ----------------------------------------------------------------------------- | |
30 | // | |
31 | METHOD | |
32 | IPAddress::to_string (WithPort withport) const -> String | |
33 | { | |
34 | String val; | |
35 | ||
36 | if (withport == IP_WITH_PORT) | |
37 | val.sprintf ("%u.%u.%u.%u:%u", octet (0), octet (1), octet (2), octet (3), port); | |
38 | else | |
39 | val.sprintf ("%u.%u.%u.%u", octet (0), octet (1), octet (2), octet (3)); | |
40 | ||
41 | return val; | |
42 | } | |
43 | ||
44 | // ----------------------------------------------------------------------------- | |
45 | // | |
46 | METHOD | |
47 | IPAddress::octet (int n) const -> unsigned char | |
48 | { | |
49 | return (host >> ((3 - n) * 8)) & 0xFF; | |
50 | } | |
51 | ||
52 | // ----------------------------------------------------------------------------- | |
53 | // | |
54 | METHOD | |
55 | IPAddress::set_octet (int n, unsigned char oct) -> void | |
56 | { | |
57 | // TODO: make a big-endian version | |
58 | host &= ~(0xFF << (3 - n) * 8); | |
59 | host |= oct << ((3 - n) * 8); | |
60 | } | |
61 | ||
62 | // ----------------------------------------------------------------------------- | |
63 | // | |
64 | METHOD | |
65 | IPAddress::compare (const IPAddress& other) const -> bool | |
66 | { | |
67 | for (int i = 0; i < 4; ++i) | |
68 | { | |
69 | if (octet (i) != other.octet (i)) | |
70 | return false; | |
71 | } | |
72 | ||
73 | if (port != 0 | |
74 | and other.port != 0 | |
75 | and port != other.port) | |
76 | { | |
77 | return false; | |
78 | } | |
79 | ||
80 | return true; | |
81 | } | |
82 | ||
83 | // ----------------------------------------------------------------------------- | |
84 | // | |
85 | METHOD | |
86 | IPAddress::operator< (const IPAddress& other) const -> bool | |
87 | { | |
88 | for (int i = 0; i < 4; ++i) | |
89 | { | |
90 | if (octet (i) != other.octet (i)) | |
91 | return octet (i) < other.octet (i); | |
92 | } | |
93 | ||
94 | return port < other.port; | |
95 | } | |
96 | ||
97 | // ----------------------------------------------------------------------------- | |
98 | // | |
99 | METHOD | |
100 | IPAddress::to_sockaddr_in() const -> sockaddr_in | |
101 | { | |
102 | sockaddr_in claddr; | |
103 | memset (&claddr, 0, sizeof claddr); | |
104 | claddr.sin_addr.s_addr = htonl (host); | |
105 | claddr.sin_port = htons (port); | |
106 | claddr.sin_family = AF_INET; | |
107 | return claddr; | |
108 | } | |
109 | ||
110 | // ----------------------------------------------------------------------------- | |
111 | // | |
112 | STATIC METHOD | |
113 | IPAddress::from_string (String input, bool* ok) -> IPAddress | |
114 | { | |
115 | unsigned int parts[4]; | |
116 | int colonpos = input.find (":"); | |
117 | String addressString = colonpos == -1 ? input : input.mid (0, colonpos); | |
118 | IPAddress value; | |
119 | ||
7
01e4e9ae323a
- fixed some problems with the ip address
Teemu Piippo <crimsondusk64@gmail.com>
parents:
5
diff
changeset
|
120 | // Try scanf the IPv4 host first |
5 | 121 | if (sscanf (addressString, "%u.%u.%u.%u", &parts[0], &parts[1], &parts[2], &parts[3])) |
122 | { | |
123 | for (short i = 0; i < 4; ++i) | |
124 | value.set_octet (i, parts[i]); | |
125 | } | |
126 | else | |
127 | { | |
7
01e4e9ae323a
- fixed some problems with the ip address
Teemu Piippo <crimsondusk64@gmail.com>
parents:
5
diff
changeset
|
128 | // Possibly a hostname, try resolve it |
01e4e9ae323a
- fixed some problems with the ip address
Teemu Piippo <crimsondusk64@gmail.com>
parents:
5
diff
changeset
|
129 | value = IPAddress::resolve (addressString, ok); |
01e4e9ae323a
- fixed some problems with the ip address
Teemu Piippo <crimsondusk64@gmail.com>
parents:
5
diff
changeset
|
130 | |
01e4e9ae323a
- fixed some problems with the ip address
Teemu Piippo <crimsondusk64@gmail.com>
parents:
5
diff
changeset
|
131 | if (*ok == false) |
01e4e9ae323a
- fixed some problems with the ip address
Teemu Piippo <crimsondusk64@gmail.com>
parents:
5
diff
changeset
|
132 | return value; |
5 | 133 | } |
134 | ||
135 | if (colonpos != -1) | |
7
01e4e9ae323a
- fixed some problems with the ip address
Teemu Piippo <crimsondusk64@gmail.com>
parents:
5
diff
changeset
|
136 | value.port = input.mid (colonpos + 1, -1).to_int(); |
5 | 137 | |
138 | return value; | |
139 | } | |
140 | ||
141 | // ----------------------------------------------------------------------------- | |
142 | // | |
143 | STATIC METHOD | |
144 | IPAddress::resolve (String node, bool* ok) -> IPAddress | |
145 | { | |
146 | struct addrinfo hints; | |
147 | struct addrinfo* lookup; | |
148 | int errorcode; | |
149 | memset (&hints, 0, sizeof hints); | |
150 | hints.ai_family = AF_INET; | |
151 | ||
152 | if ((errorcode = getaddrinfo (node, nullptr, &hints, &lookup)) != 0) | |
153 | { | |
154 | *ok = false; | |
155 | return IPAddress(); | |
156 | } | |
157 | ||
158 | IPAddress result; | |
159 | assert (lookup != nullptr); | |
160 | sockaddr_in* addr = reinterpret_cast<struct sockaddr_in*> (lookup[0].ai_addr); | |
161 | result.host = ntohl (addr->sin_addr.s_addr); | |
162 | result.port = ntohs (addr->sin_port); | |
163 | freeaddrinfo (lookup); | |
164 | *ok = true; | |
165 | return result; | |
166 | } |