00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 #include <stdio.h>
00050
00051 #include "ipcalc.h"
00052
00053 #define IN6ADDR_V4MAPPED_LOOPBACK_INIT \
00054 { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
00055 0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x01 } } }
00056
00057 const struct in6_addr in6addr_v4mapped_loopback = IN6ADDR_V4MAPPED_LOOPBACK_INIT;
00058
00059
00060 const union olsr_ip_addr all_zero = {.v6 = IN6ADDR_ANY_INIT };
00061
00062
00063 const struct olsr_ip_prefix ipv4_internet_route =
00064 {
00065 .prefix.v4.s_addr = 0,
00066 .prefix_len = 0
00067 };
00068
00069
00070 const struct olsr_ip_prefix ipv6_mappedv4_route =
00071 {
00072 .prefix.v6.s6_addr = { 0,0,0,0,0,0,0,0,0,0,0xff,0xff,0,0,0,0 },
00073 .prefix_len = 96
00074 };
00075
00076
00077 const struct olsr_ip_prefix ipv6_internet_route =
00078 {
00079 .prefix.v6.s6_addr = { 0x20, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
00080 .prefix_len = 3
00081 };
00082
00083
00084 void
00085 ip_map_4to6(union olsr_ip_addr *addr) {
00086
00087 memmove(&addr->v6.s6_addr[12], &addr->v4.s_addr, 4 * sizeof(uint8_t));
00088 memset(&addr->v6.s6_addr[0], 0x00, 10 * sizeof(uint8_t));
00089 memset(&addr->v6.s6_addr[10], 0xff, 2 * sizeof(uint8_t));
00090 }
00091
00092 int
00093 prefix_to_netmask(uint8_t * a, int len, uint8_t prefixlen)
00094 {
00095 int i = 0;
00096 const int end = MIN(len, prefixlen / 8);
00097
00098 while (i < end) {
00099 a[i++] = 0xff;
00100 }
00101 if (i < len) {
00102 a[i++] = 0xff << (8 - (prefixlen % 8));
00103 while (i < len) {
00104 a[i++] = 0;
00105 }
00106 }
00107
00108 return (prefixlen <= len * 8);
00109 }
00110
00111 uint8_t
00112 netmask_to_prefix(const uint8_t * adr, int len)
00113 {
00114 const uint8_t *const a_end = adr + len;
00115 uint16_t prefix = 0;
00116 const uint8_t *a;
00117 #if 0
00118 struct ipaddr_str buf;
00119 #endif
00120
00121 for (a = adr; a < a_end && *a == 0xff; a++) {
00122 prefix += 8;
00123 }
00124 if (a < a_end) {
00125
00126 switch (*a) {
00127 case 0:
00128 prefix += 0;
00129 break;
00130 case 128:
00131 prefix += 1;
00132 break;
00133 case 192:
00134 prefix += 2;
00135 break;
00136 case 224:
00137 prefix += 3;
00138 break;
00139 case 240:
00140 prefix += 4;
00141 break;
00142 case 248:
00143 prefix += 5;
00144 break;
00145 case 252:
00146 prefix += 6;
00147 break;
00148 case 254:
00149 prefix += 7;
00150 break;
00151 case 255:
00152 prefix += 8;
00153 break;
00154 default:
00155
00156
00157 prefix = len*8;
00158 break;
00159 }
00160 }
00161 return prefix;
00162 }
00163
00164 const char *
00165 ip_prefix_to_string(int af, struct ipprefix_str *const buf, const struct olsr_ip_prefix *prefix)
00166 {
00167 int len;
00168 inet_ntop(af, &prefix->prefix, buf->buf, sizeof(buf->buf));
00169 len = strlen(buf->buf);
00170 snprintf(buf->buf + len, sizeof(buf->buf) - len, "/%d", prefix->prefix_len);
00171 return buf->buf;
00172 }
00173
00174
00175
00176
00177
00178 int
00179 ip_in_net(const union olsr_ip_addr *ipaddr, const struct olsr_ip_prefix *net, int ip_version)
00180 {
00181 int rv;
00182 if (ip_version == AF_INET) {
00183 uint32_t netmask = ntohl(prefix_to_netmask4(net->prefix_len));
00184 rv = (ipaddr->v4.s_addr & netmask) == (net->prefix.v4.s_addr & netmask);
00185 } else {
00186
00187 uint32_t netmask;
00188 const uint32_t *i = (const uint32_t *) (ARM_NOWARN_ALIGN(&ipaddr->v6.s6_addr));
00189 const uint32_t *n = (const uint32_t *) (ARM_NOWARN_ALIGN(&net->prefix.v6.s6_addr));
00190 unsigned int prefix_len;
00191
00192 for (prefix_len = net->prefix_len; prefix_len > 32; prefix_len -= 32) {
00193 if (*i != *n) {
00194 return false;
00195 }
00196 i++;
00197 n++;
00198 }
00199
00200 netmask = ntohl(prefix_to_netmask4(prefix_len));
00201 rv = (*i & netmask) == (*n & netmask);
00202 }
00203 return rv;
00204 }
00205
00206 static const char *
00207 sockaddr4_to_string(char *const buf, int bufsize, const struct sockaddr *const addr)
00208 {
00209 char addrbuf[INET6_ADDRSTRLEN];
00210 const struct sockaddr_in *const sin4 = (const struct sockaddr_in *)(ARM_CONST_NOWARN_ALIGN)addr;
00211 snprintf(buf, bufsize, "IPv4/%s:%d", inet_ntop(AF_INET, &sin4->sin_addr, addrbuf, sizeof(addrbuf)), sin4->sin_port);
00212 return buf;
00213 }
00214
00215 static const char *
00216 sockaddr6_to_string(char *const buf, int bufsize, const struct sockaddr *const addr)
00217 {
00218 char addrbuf[INET6_ADDRSTRLEN];
00219 const struct sockaddr_in6 *const sin6 = (const struct sockaddr_in6 *)(ARM_CONST_NOWARN_ALIGN)addr;
00220 snprintf(buf, bufsize,
00221 "IPv6/[%s]:%d/%x/%x",
00222 inet_ntop(AF_INET6, &sin6->sin6_addr, addrbuf, sizeof(addrbuf)),
00223 sin6->sin6_port, (unsigned)sin6->sin6_flowinfo, (unsigned)sin6->sin6_scope_id);
00224 return buf;
00225 }
00226
00227 const char *
00228 sockaddr_to_string(char *const buf, int bufsize, const struct sockaddr *const addr, unsigned int addrsize)
00229 {
00230 switch (addr->sa_family) {
00231 case AF_INET:
00232 return sockaddr4_to_string(buf, bufsize, addr);
00233 case AF_INET6:
00234 return sockaddr6_to_string(buf, bufsize, addr);
00235 default:
00236 {
00237 const int size = MIN(addrsize - sizeof(addr->sa_family), sizeof(addr->sa_data));
00238 char sep = '/';
00239 int i;
00240 int len = snprintf(buf, bufsize, "%d", addr->sa_family);
00241 for (i = 0; i < size; i++) {
00242 len += snprintf(buf + len, bufsize - len, "%c%02x", sep, addr->sa_data[i]);
00243 sep = ' ';
00244 }
00245 }
00246 break;
00247 }
00248 return buf;
00249 }
00250
00251 bool is_prefix_inetgw(const struct olsr_ip_prefix *prefix) {
00252 if (olsr_cnf->ip_version == AF_INET && ip_prefix_is_v4_inetgw(prefix)) {
00253 return true;
00254 }
00255 if (olsr_cnf->ip_version == AF_INET6) {
00256 if (ip_prefix_is_v6_inetgw(prefix) || ip_prefix_is_mappedv4_inetgw(prefix)) {
00257 return true;
00258 }
00259 }
00260 return false;
00261 }
00262
00263
00264
00265
00266
00267
00268