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 #ifndef _IPCALC
00050 #define _IPCALC
00051
00052 #include "olsr_types.h"
00053 #include "defs.h"
00054 #include "olsr_cfg.h"
00055 #include "common/string.h"
00056
00057 #include <limits.h>
00058 #include <string.h>
00059 #include <arpa/inet.h>
00060
00061 extern const union olsr_ip_addr all_zero;
00062
00063 extern const struct olsr_ip_prefix ipv4_internet_route;
00064 extern const struct olsr_ip_prefix ipv6_mappedv4_route;
00065 extern const struct olsr_ip_prefix ipv6_internet_route;
00066
00067 struct ipaddr_str {
00068 char buf[MAX(INET6_ADDRSTRLEN, INET_ADDRSTRLEN)];
00069 };
00070
00071 struct ipprefix_str {
00072
00073 char buf[MAX(INET6_ADDRSTRLEN + 1 + 3, INET_ADDRSTRLEN + 1 + 2)];
00074 };
00075
00076
00077
00078
00079 static INLINE int
00080 ip4cmp(const struct in_addr *a, const struct in_addr *b)
00081 {
00082 return a->s_addr > b->s_addr ? +1 : a->s_addr < b->s_addr ? -1 : 0;
00083 }
00084
00085 static INLINE int
00086 ip6cmp(const struct in6_addr *a, const struct in6_addr *b)
00087 {
00088 return memcmp(a, b, sizeof(*a));
00089 }
00090
00091 static INLINE int
00092 ipcmp(int ip_version, const union olsr_ip_addr *a, const union olsr_ip_addr *b)
00093 {
00094 return ip_version == AF_INET ? ip4cmp(&a->v4, &b->v4) : ip6cmp(&a->v6, &b->v6);
00095 }
00096
00097 static INLINE int
00098 olsr_ipcmp(const union olsr_ip_addr *a, const union olsr_ip_addr *b)
00099 {
00100 return ipcmp(olsr_cnf->ip_version, a, b);
00101 }
00102
00103
00104
00105
00106 static INLINE void
00107 genipcopy(void *dst, const void *src)
00108 {
00109 memcpy(dst, src, olsr_cnf->ipsize);
00110 }
00111
00112 int ip_in_net(const union olsr_ip_addr *ipaddr, const struct olsr_ip_prefix *net, int ip_version);
00113
00114
00115 int EXPORT(prefix_to_netmask) (uint8_t *, int, uint8_t);
00116
00117 static INLINE int
00118 olsr_prefix_to_netmask(union olsr_ip_addr *adr, uint8_t prefixlen)
00119 {
00120 return prefix_to_netmask(adr->v6.s6_addr, olsr_cnf->ipsize, prefixlen);
00121 }
00122
00123 uint8_t EXPORT(netmask_to_prefix) (const uint8_t *, int);
00124
00125 static INLINE uint8_t
00126 olsr_netmask_to_prefix(const union olsr_ip_addr *adr)
00127 {
00128 return netmask_to_prefix(adr->v6.s6_addr, olsr_cnf->ipsize);
00129 }
00130
00131 static INLINE uint8_t
00132 olsr_netmask4_to_prefix(const uint32_t * a)
00133 {
00134 return netmask_to_prefix((const uint8_t *)a, sizeof(*a));
00135 }
00136 static INLINE uint8_t
00137 olsr_netmask6_to_prefix(const struct in6_addr *a)
00138 {
00139 return netmask_to_prefix((const uint8_t *)a, sizeof(*a));
00140 }
00141
00142 static INLINE const char *
00143 ip4_to_string(struct ipaddr_str *const buf, const struct in_addr addr4)
00144 {
00145 return inet_ntop(AF_INET, &addr4, buf->buf, sizeof(buf->buf));
00146 }
00147
00148 static INLINE const char *
00149 ip6_to_string(struct ipaddr_str *const buf, const struct in6_addr *const addr6)
00150 {
00151 return inet_ntop(AF_INET6, addr6, buf->buf, sizeof(buf->buf));
00152 }
00153
00154 static INLINE const char *
00155 olsr_sockaddr_to_string(struct ipaddr_str *const buf, const union olsr_sockaddr *s) {
00156 if (s->storage.ss_family == AF_INET) {
00157 return inet_ntop(AF_INET, &s->v4.sin_addr, buf->buf, sizeof(buf->buf));
00158 }
00159 else if (s->storage.ss_family == AF_INET6) {
00160 return inet_ntop(AF_INET6, &s->v6.sin6_addr, buf->buf, sizeof(buf->buf));
00161 }
00162 else {
00163 strscpy(buf->buf, "unkown ip family", sizeof(buf->buf));
00164 return buf->buf;
00165 }
00166 }
00167
00168 static INLINE const char *
00169 ip_to_string(int af, struct ipaddr_str *const buf, const union olsr_ip_addr *addr)
00170 {
00171 return inet_ntop(af, addr, buf->buf, sizeof(buf->buf));
00172 }
00173
00174 static INLINE const char *
00175 olsr_ip_to_string(struct ipaddr_str *const buf, const union olsr_ip_addr *addr)
00176 {
00177 return ip_to_string(olsr_cnf->ip_version, buf, addr);
00178 }
00179
00180 const char *EXPORT(ip_prefix_to_string) (int af, struct ipprefix_str * const buf, const struct olsr_ip_prefix * prefix);
00181
00182 static INLINE const char *
00183 olsr_ip_prefix_to_string(struct ipprefix_str *const buf, const struct olsr_ip_prefix *prefix)
00184 {
00185 return ip_prefix_to_string(olsr_cnf->ip_version, buf, prefix);
00186 }
00187
00188 const char *sockaddr_to_string(char *buf, int bufsize, const struct sockaddr *const addr, unsigned int addrsize);
00189
00190
00191
00192
00193 static INLINE uint32_t
00194 prefix_to_netmask4(uint8_t prefixlen)
00195 {
00196 return prefixlen == 0 ? 0 : (~0U << (32 - prefixlen));
00197 }
00198
00199 extern const struct in6_addr EXPORT(in6addr_v4mapped_loopback);
00200
00201 void EXPORT(ip_map_4to6) (union olsr_ip_addr *ip);
00202
00203 static INLINE bool
00204 is_prefix_niit_ipv6(const struct olsr_ip_prefix *p) {
00205 return olsr_cnf->ip_version == AF_INET6 && IN6_IS_ADDR_V4MAPPED(&p->prefix.v6)
00206 && p->prefix_len >= ipv6_mappedv4_route.prefix_len;
00207 }
00208
00209 static INLINE struct olsr_ip_prefix *
00210 prefix_mappedv4_to_v4(struct olsr_ip_prefix *v4, const struct olsr_ip_prefix *v6) {
00211 memcpy(&v4->prefix.v4, &v6->prefix.v6.s6_addr[12], sizeof(struct in_addr));
00212 v4->prefix_len = v6->prefix_len - 96;
00213 return v4;
00214 }
00215
00216 static INLINE bool
00217 ip_is_linklocal(const union olsr_ip_addr *ip) {
00218 return olsr_cnf->ip_version == AF_INET6
00219 && ip->v6.s6_addr[0] == 0xfe && (ip->v6.s6_addr[1] & 0xc0) == 0x80;
00220 }
00221
00222 static INLINE bool
00223 ip_prefix_is_mappedv4(const struct olsr_ip_prefix *prefix) {
00224 return prefix->prefix_len >= ipv6_mappedv4_route.prefix_len
00225 && memcmp(prefix, &ipv6_mappedv4_route, ipv6_mappedv4_route.prefix_len / 8) == 0;
00226 }
00227
00228 static INLINE bool
00229 ip_prefix_is_mappedv4_inetgw(const struct olsr_ip_prefix *prefix) {
00230 return prefix->prefix_len == ipv6_mappedv4_route.prefix_len
00231 && memcmp(prefix, &ipv6_mappedv4_route, ipv6_mappedv4_route.prefix_len / 8) == 0;
00232 }
00233
00234 static INLINE bool
00235 ip_prefix_is_v4_inetgw(const struct olsr_ip_prefix *prefix) {
00236 return prefix->prefix_len == ipv4_internet_route.prefix_len
00237 && prefix->prefix.v4.s_addr == ipv4_internet_route.prefix.v4.s_addr;
00238 }
00239
00240 static INLINE bool
00241 ip_prefix_is_v6_inetgw(const struct olsr_ip_prefix *prefix) {
00242 return prefix->prefix_len == ipv6_internet_route.prefix_len
00243 && memcmp(prefix, &ipv6_internet_route, ipv6_internet_route.prefix_len/8) == 0;
00244 }
00245
00246 extern bool is_prefix_inetgw(const struct olsr_ip_prefix *prefix);
00247
00248 #endif
00249
00250
00251
00252
00253
00254
00255