Permalink
Browse files

do not relay IPv4 mapped address traffic. this can constitute DoS att…

…ack.

NetBSD PR: 8640
  • Loading branch information...
1 parent f113075 commit cdec47026c52548dbdcbe24cf1f114e614b6845f itojun committed Dec 19, 1999
Showing with 31 additions and 17 deletions.
  1. +31 −17 kame/kame/faithd/faithd.c
View
@@ -217,7 +217,7 @@ main(int argc, char *argv[])
hints.ai_protocol = 0;
error = getaddrinfo(NULL, service, &hints, &res);
if (error)
- exit_error("gaddrinfo: %s", gai_strerror(error));
+ exit_error("getaddrinfo: %s", gai_strerror(error));
s_wld = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (s_wld == -1)
@@ -507,28 +507,42 @@ faith_prefix(struct sockaddr *dst)
struct myaddrs *p;
struct sockaddr_in6 *sin6;
struct sockaddr_in *sin4;
+ struct sockaddr_in6 *dst6;
+ struct sockaddr_in *dst4;
+ struct sockaddr_in dstmap;
+
+ if (dst->sa_family == AF_INET6
+ && IN6_IS_ADDR_V4MAPPED(&dst6->sin6_addr)) {
+ /* ugly... */
+ memset(&dstmap, 0, sizeof(dstmap));
+ dstmap.sin_family = AF_INET;
+ dstmap.sin_len = sizeof(dstmap);
+ memcpy(&dstmap.sin_addr, &dst6->sin6_addr.s6_addr[12],
+ sizeof(dstmap.sin_addr));
+ dst = (struct sockaddr *)&dstmap;
+ }
+
+ dst6 = (struct sockaddr_in6 *)dst;
+ dst4 = (struct sockaddr_in *)dst;
for (p = myaddrs; p; p = p->next) {
sin6 = (struct sockaddr_in6 *)p->addr;
sin4 = (struct sockaddr_in *)p->addr;
- /* ugly! */
- if (p->addr->sa_len == dst->sa_len
- && p->addr->sa_family == dst->sa_family) {
- struct sockaddr_in6 *dst6 = (struct sockaddr_in6 *)dst;
- struct sockaddr_in *dst4 = (struct sockaddr_in *)dst;
-
- switch (dst->sa_family) {
- case AF_INET6:
- if (sin6->sin6_scope_id == dst6->sin6_scope_id
- && memcmp(&sin6->sin6_addr, &dst6->sin6_addr, 16) == 0)
- return 0;
- break;
- case AF_INET:
- if (sin4->sin_addr.s_addr == dst4->sin_addr.s_addr)
+ if (p->addr->sa_len != dst->sa_len
+ || p->addr->sa_family != dst->sa_family)
+ continue;
+
+ switch (dst->sa_family) {
+ case AF_INET6:
+ if (sin6->sin6_scope_id == dst6->sin6_scope_id
+ && IN6_ARE_ADDR_EQUAL(&sin6->sin6_addr, &dst6->sin6_addr) == 0)
return 0;
- break;
- }
+ break;
+ case AF_INET:
+ if (sin4->sin_addr.s_addr == dst4->sin_addr.s_addr)
+ return 0;
+ break;
}
}
return 1;

0 comments on commit cdec470

Please sign in to comment.