00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "config.h"
00012
00013 #include <sys/types.h>
00014 #ifdef HAVE_NET_IF_H
00015 # include <sys/socket.h>
00016 # include <net/if.h>
00017 #endif
00018 #ifdef HAVE_NET_IF_DL_H
00019 # include <net/if_dl.h>
00020 #endif
00021 #ifdef HAVE_NET_RAW_H
00022 # include <net/raw.h>
00023 #endif
00024
00025 #include <ctype.h>
00026 #include <errno.h>
00027 #include <stdio.h>
00028 #include <stdlib.h>
00029 #include <string.h>
00030
00031 #include "dnet.h"
00032
00033 #ifndef MAXHOSTNAMELEN
00034 # define MAXHOSTNAMELEN 256
00035 #endif
00036
00037 union sockunion {
00038 #ifdef HAVE_NET_IF_DL_H
00039 struct sockaddr_dl sdl;
00040 #endif
00041 struct sockaddr_in sin;
00042 #ifdef HAVE_SOCKADDR_IN6
00043 struct sockaddr_in6 sin6;
00044 #endif
00045 struct sockaddr sa;
00046 #ifdef AF_RAW
00047 struct sockaddr_raw sr;
00048 #endif
00049 };
00050
00051 int
00052 addr_cmp(const struct addr *a, const struct addr *b)
00053 {
00054 int i, j, k;
00055
00056
00057 if ((i = a->addr_type - b->addr_type) != 0)
00058 return (i);
00059
00060
00061 if ((i = a->addr_bits - b->addr_bits) != 0)
00062 return (i);
00063
00064 j = b->addr_bits / 8;
00065
00066 for (i = 0; i < j; i++) {
00067 if ((k = a->addr_data8[i] - b->addr_data8[i]) != 0)
00068 return (k);
00069 }
00070 if ((k = b->addr_bits % 8) == 0)
00071 return (0);
00072
00073 k = ~0 << (8 - k);
00074 i = b->addr_data8[j] & k;
00075 j = a->addr_data8[j] & k;
00076
00077 return (j - i);
00078 }
00079
00080 int
00081 addr_net(const struct addr *a, struct addr *b)
00082 {
00083 uint32_t mask;
00084 int i, j;
00085
00086 if (a->addr_type == ADDR_TYPE_IP) {
00087 addr_btom(a->addr_bits, &mask, IP_ADDR_LEN);
00088 b->addr_type = ADDR_TYPE_IP;
00089 b->addr_bits = IP_ADDR_BITS;
00090 b->addr_ip = a->addr_ip & mask;
00091 } else if (a->addr_type == ADDR_TYPE_ETH) {
00092 memcpy(b, a, sizeof(*b));
00093 if (a->addr_data8[0] & 0x1)
00094 memset(b->addr_data8 + 3, 0, 3);
00095 b->addr_bits = ETH_ADDR_BITS;
00096 } else if (a->addr_type == ADDR_TYPE_IP6) {
00097 b->addr_type = ADDR_TYPE_IP6;
00098 b->addr_bits = IP6_ADDR_BITS;
00099 memset(&b->addr_ip6, 0, IP6_ADDR_LEN);
00100
00101 switch ((i = a->addr_bits / 32)) {
00102 case 4: b->addr_data32[3] = a->addr_data32[3];
00103 case 3: b->addr_data32[2] = a->addr_data32[2];
00104 case 2: b->addr_data32[1] = a->addr_data32[1];
00105 case 1: b->addr_data32[0] = a->addr_data32[0];
00106 }
00107 if ((j = a->addr_bits % 32) > 0) {
00108 addr_btom(j, &mask, sizeof(mask));
00109 b->addr_data32[i] = a->addr_data32[i] & mask;
00110 }
00111 } else
00112 return (-1);
00113
00114 return (0);
00115 }
00116
00117 int
00118 addr_bcast(const struct addr *a, struct addr *b)
00119 {
00120 struct addr mask;
00121
00122 if (a->addr_type == ADDR_TYPE_IP) {
00123 addr_btom(a->addr_bits, &mask.addr_ip, IP_ADDR_LEN);
00124 b->addr_type = ADDR_TYPE_IP;
00125 b->addr_bits = IP_ADDR_BITS;
00126 b->addr_ip = (a->addr_ip & mask.addr_ip) |
00127 (~0L & ~mask.addr_ip);
00128 } else if (a->addr_type == ADDR_TYPE_ETH) {
00129 b->addr_type = ADDR_TYPE_ETH;
00130 b->addr_bits = ETH_ADDR_BITS;
00131 memcpy(&b->addr_eth, ETH_ADDR_BROADCAST, ETH_ADDR_LEN);
00132 } else {
00133
00134 errno = EINVAL;
00135 return (-1);
00136 }
00137 return (0);
00138 }
00139
00140 char *
00141 addr_ntop(const struct addr *src, char *dst, size_t size)
00142 {
00143 if (src->addr_type == ADDR_TYPE_IP && size >= 20) {
00144 if (ip_ntop(&src->addr_ip, dst, size) != NULL) {
00145 if (src->addr_bits != IP_ADDR_BITS)
00146 sprintf(dst + strlen(dst), "/%d",
00147 src->addr_bits);
00148 return (dst);
00149 }
00150 } else if (src->addr_type == ADDR_TYPE_IP6 && size >= 42) {
00151 if (ip6_ntop(&src->addr_ip6, dst, size) != NULL) {
00152 if (src->addr_bits != IP6_ADDR_BITS)
00153 sprintf(dst + strlen(dst), "/%d",
00154 src->addr_bits);
00155 return (dst);
00156 }
00157 } else if (src->addr_type == ADDR_TYPE_ETH && size >= 18) {
00158 if (src->addr_bits == ETH_ADDR_BITS)
00159 return (eth_ntop(&src->addr_eth, dst, size));
00160 }
00161 errno = EINVAL;
00162 return (NULL);
00163 }
00164
00165 int
00166 addr_pton(const char *src, struct addr *dst)
00167 {
00168 struct hostent *hp;
00169 char *ep, tmp[300];
00170 long bits = -1;
00171 int i;
00172
00173 for (i = 0; i < (int)sizeof(tmp) - 1; i++) {
00174 if (src[i] == '/') {
00175 tmp[i] = '\0';
00176 if (strchr(&src[i + 1], '.')) {
00177 uint32_t m;
00178 uint16_t b;
00179
00180 if (ip_pton(&src[i + 1], &m) != 0) {
00181 errno = EINVAL;
00182 return (-1);
00183 }
00184 addr_mtob(&m, sizeof(m), &b);
00185 bits = b;
00186 } else {
00187 bits = strtol(&src[i + 1], &ep, 10);
00188 if (ep == src || *ep != '\0' || bits < 0) {
00189 errno = EINVAL;
00190 return (-1);
00191 }
00192 }
00193 break;
00194 } else if ((tmp[i] = src[i]) == '\0')
00195 break;
00196 }
00197 if (ip_pton(tmp, &dst->addr_ip) == 0) {
00198 dst->addr_type = ADDR_TYPE_IP;
00199 dst->addr_bits = IP_ADDR_BITS;
00200 } else if (eth_pton(tmp, &dst->addr_eth) == 0) {
00201 dst->addr_type = ADDR_TYPE_ETH;
00202 dst->addr_bits = ETH_ADDR_BITS;
00203 } else if (ip6_pton(tmp, &dst->addr_ip6) == 0) {
00204 dst->addr_type = ADDR_TYPE_IP6;
00205 dst->addr_bits = IP6_ADDR_BITS;
00206 } else if ((hp = gethostbyname(tmp)) != NULL) {
00207 memcpy(&dst->addr_ip, hp->h_addr, IP_ADDR_LEN);
00208 dst->addr_type = ADDR_TYPE_IP;
00209 dst->addr_bits = IP_ADDR_BITS;
00210 } else {
00211 errno = EINVAL;
00212 return (-1);
00213 }
00214 if (bits >= 0) {
00215 if (bits > dst->addr_bits) {
00216 errno = EINVAL;
00217 return (-1);
00218 }
00219 dst->addr_bits = (uint16_t)bits;
00220 }
00221 return (0);
00222 }
00223
00224 char *
00225 addr_ntoa(const struct addr *a)
00226 {
00227 static char *p, buf[BUFSIZ];
00228 char *q = NULL;
00229
00230 if (p == NULL || p > buf + sizeof(buf) - 64 )
00231 p = buf;
00232
00233 if (addr_ntop(a, p, (buf + sizeof(buf)) - p) != NULL) {
00234 q = p;
00235 p += strlen(p) + 1;
00236 }
00237 return (q);
00238 }
00239
00240 int
00241 addr_ntos(const struct addr *a, struct sockaddr *sa)
00242 {
00243 union sockunion *so = (union sockunion *)sa;
00244
00245 switch (a->addr_type) {
00246 case ADDR_TYPE_ETH:
00247 #ifdef HAVE_NET_IF_DL_H
00248 memset(&so->sdl, 0, sizeof(so->sdl));
00249 # ifdef HAVE_SOCKADDR_SA_LEN
00250 so->sdl.sdl_len = sizeof(so->sdl);
00251 # endif
00252 so->sdl.sdl_family = AF_LINK;
00253 so->sdl.sdl_alen = ETH_ADDR_LEN;
00254 memcpy(LLADDR(&so->sdl), &a->addr_eth, ETH_ADDR_LEN);
00255 #else
00256 memset(sa, 0, sizeof(*sa));
00257 # ifdef AF_LINK
00258 sa->sa_family = AF_LINK;
00259 # else
00260 sa->sa_family = AF_UNSPEC;
00261 # endif
00262 memcpy(sa->sa_data, &a->addr_eth, ETH_ADDR_LEN);
00263 #endif
00264 break;
00265 #ifdef HAVE_SOCKADDR_IN6
00266 case ADDR_TYPE_IP6:
00267 memset(&so->sin6, 0, sizeof(so->sin6));
00268 #ifdef HAVE_SOCKADDR_SA_LEN
00269 so->sin6.sin6_len = sizeof(so->sin6);
00270 #endif
00271 so->sin6.sin6_family = AF_INET6;
00272 memcpy(&so->sin6.sin6_addr, &a->addr_ip6, IP6_ADDR_LEN);
00273 break;
00274 #endif
00275 case ADDR_TYPE_IP:
00276 memset(&so->sin, 0, sizeof(so->sin));
00277 #ifdef HAVE_SOCKADDR_SA_LEN
00278 so->sin.sin_len = sizeof(so->sin);
00279 #endif
00280 so->sin.sin_family = AF_INET;
00281 so->sin.sin_addr.s_addr = a->addr_ip;
00282 break;
00283 default:
00284 errno = EINVAL;
00285 return (-1);
00286 }
00287 return (0);
00288 }
00289
00290 int
00291 addr_ston(const struct sockaddr *sa, struct addr *a)
00292 {
00293 union sockunion *so = (union sockunion *)sa;
00294
00295 memset(a, 0, sizeof(*a));
00296
00297 switch (sa->sa_family) {
00298 #ifdef HAVE_NET_IF_DL_H
00299 case AF_LINK:
00300 if (so->sdl.sdl_alen != ETH_ADDR_LEN) {
00301 errno = EINVAL;
00302 return (-1);
00303 }
00304 a->addr_type = ADDR_TYPE_ETH;
00305 a->addr_bits = ETH_ADDR_BITS;
00306 memcpy(&a->addr_eth, LLADDR(&so->sdl), ETH_ADDR_LEN);
00307 break;
00308 #endif
00309 case AF_UNSPEC:
00310 case ARP_HRD_ETH:
00311 a->addr_type = ADDR_TYPE_ETH;
00312 a->addr_bits = ETH_ADDR_BITS;
00313 memcpy(&a->addr_eth, sa->sa_data, ETH_ADDR_LEN);
00314 break;
00315
00316 #ifdef AF_RAW
00317 case AF_RAW:
00318 a->addr_type = ADDR_TYPE_ETH;
00319 a->addr_bits = ETH_ADDR_BITS;
00320 memcpy(&a->addr_eth, so->sr.sr_addr, ETH_ADDR_LEN);
00321 break;
00322 #endif
00323 #ifdef HAVE_SOCKADDR_IN6
00324 case AF_INET6:
00325 a->addr_type = ADDR_TYPE_IP6;
00326 a->addr_bits = IP6_ADDR_BITS;
00327 memcpy(&a->addr_ip6, &so->sin6.sin6_addr, IP6_ADDR_LEN);
00328 break;
00329 #endif
00330 case AF_INET:
00331 a->addr_type = ADDR_TYPE_IP;
00332 a->addr_bits = IP_ADDR_BITS;
00333 a->addr_ip = so->sin.sin_addr.s_addr;
00334 break;
00335 default:
00336 errno = EINVAL;
00337 return (-1);
00338 }
00339 return (0);
00340 }
00341
00342 int
00343 addr_btos(uint16_t bits, struct sockaddr *sa)
00344 {
00345 union sockunion *so = (union sockunion *)sa;
00346
00347 #ifdef HAVE_SOCKADDR_IN6
00348 if (bits > IP_ADDR_BITS && bits <= IP6_ADDR_BITS) {
00349 memset(&so->sin6, 0, sizeof(so->sin6));
00350 #ifdef HAVE_SOCKADDR_SA_LEN
00351 so->sin6.sin6_len = IP6_ADDR_LEN + (bits / 8) + (bits % 8);
00352 #endif
00353 so->sin6.sin6_family = AF_INET6;
00354 return (addr_btom(bits, &so->sin6.sin6_addr, IP6_ADDR_LEN));
00355 } else
00356 #endif
00357 if (bits <= IP_ADDR_BITS) {
00358 memset(&so->sin, 0, sizeof(so->sin));
00359 #ifdef HAVE_SOCKADDR_SA_LEN
00360 so->sin.sin_len = IP_ADDR_LEN + (bits / 8) + (bits % 8);
00361 #endif
00362 so->sin.sin_family = AF_INET;
00363 return (addr_btom(bits, &so->sin.sin_addr, IP_ADDR_LEN));
00364 }
00365 errno = EINVAL;
00366 return (-1);
00367 }
00368
00369 int
00370 addr_stob(const struct sockaddr *sa, uint16_t *bits)
00371 {
00372 union sockunion *so = (union sockunion *)sa;
00373 int i, j, len;
00374 uint16_t n;
00375 u_char *p;
00376
00377 #ifdef HAVE_SOCKADDR_IN6
00378 if (sa->sa_family == AF_INET6) {
00379 len = IP6_ADDR_LEN;
00380 p = (u_char *)&so->sin6.sin6_addr;
00381 } else
00382 #endif
00383 {
00384 #ifdef HAVE_SOCKADDR_SA_LEN
00385 if ((len = sa->sa_len - IP_ADDR_LEN) > IP_ADDR_LEN)
00386 #endif
00387 len = IP_ADDR_LEN;
00388 p = (u_char *)&so->sin.sin_addr.s_addr;
00389 }
00390 for (n = i = 0; i < len; i++, n += 8) {
00391 if (p[i] != 0xff)
00392 break;
00393 }
00394 if (i != len && p[i]) {
00395 for (j = 7; j > 0; j--, n++) {
00396 if ((p[i] & (1 << j)) == 0)
00397 break;
00398 }
00399 }
00400 *bits = n;
00401
00402 return (0);
00403 }
00404
00405 int
00406 addr_btom(uint16_t bits, void *mask, size_t size)
00407 {
00408 int net, host;
00409 u_char *p;
00410
00411 if (size == IP_ADDR_LEN) {
00412 if (bits > IP_ADDR_BITS) {
00413 errno = EINVAL;
00414 return (-1);
00415 }
00416 *(uint32_t *)mask = bits ?
00417 htonl(~0 << (IP_ADDR_BITS - bits)) : 0;
00418 } else {
00419 if (size * 8 < bits) {
00420 errno = EINVAL;
00421 return (-1);
00422 }
00423 p = (u_char *)mask;
00424
00425 if ((net = bits / 8) > 0)
00426 memset(p, 0xff, net);
00427
00428 if ((host = bits % 8) > 0) {
00429 p[net] = 0xff << (8 - host);
00430 memset(&p[net + 1], 0, size - net - 1);
00431 } else
00432 memset(&p[net], 0, size - net);
00433 }
00434 return (0);
00435 }
00436
00437 int
00438 addr_mtob(const void *mask, size_t size, uint16_t *bits)
00439 {
00440 uint16_t n;
00441 u_char *p;
00442 int i, j;
00443
00444 p = (u_char *)mask;
00445
00446 for (n = i = 0; i < (int)size; i++, n += 8) {
00447 if (p[i] != 0xff)
00448 break;
00449 }
00450 if (i != (int)size && p[i]) {
00451 for (j = 7; j > 0; j--, n++) {
00452 if ((p[i] & (1 << j)) == 0)
00453 break;
00454 }
00455 }
00456 *bits = n;
00457
00458 return (0);
00459 }