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