diff --git a/icmp.c b/icmp.c index b676a1a..f2cc4d6 100644 --- a/icmp.c +++ b/icmp.c @@ -154,17 +154,21 @@ void icmpv6_sock_handler(const struct ctx *c, union epoll_ref ref) * icmp_tap_handler() - Handle packets from tap * @c: Execution context * @af: Address family, AF_INET or AF_INET6 - * @addr: Destination address + * @saddr: Source address + * @daddr: Destination address * @p: Packet pool, single packet with ICMP/ICMPv6 header * @now: Current timestamp * * Return: count of consumed packets (always 1, even if malformed) */ -int icmp_tap_handler(const struct ctx *c, int af, const void *addr, +int icmp_tap_handler(const struct ctx *c, int af, + const void *saddr, const void *daddr, const struct pool *p, const struct timespec *now) { size_t plen; + (void)saddr; + if (af == AF_INET) { struct sockaddr_in sa = { .sin_family = AF_INET, @@ -210,7 +214,7 @@ int icmp_tap_handler(const struct ctx *c, int af, const void *addr, icmp_id_map[V4][id].ts = now->tv_sec; bitmap_set(icmp_act[V4], id); - sa.sin_addr = *(struct in_addr *)addr; + sa.sin_addr = *(struct in_addr *)daddr; if (sendto(s, ih, sizeof(*ih) + plen, MSG_NOSIGNAL, (struct sockaddr *)&sa, sizeof(sa)) < 0) { debug("ICMP: failed to relay request to socket"); @@ -264,7 +268,7 @@ int icmp_tap_handler(const struct ctx *c, int af, const void *addr, icmp_id_map[V6][id].ts = now->tv_sec; bitmap_set(icmp_act[V6], id); - sa.sin6_addr = *(struct in6_addr *)addr; + sa.sin6_addr = *(struct in6_addr *)daddr; if (sendto(s, ih, sizeof(*ih) + plen, MSG_NOSIGNAL, (struct sockaddr *)&sa, sizeof(sa)) < 1) { debug("ICMPv6: failed to relay request to socket"); diff --git a/icmp.h b/icmp.h index 32f0c47..00d10ea 100644 --- a/icmp.h +++ b/icmp.h @@ -12,7 +12,8 @@ struct ctx; void icmp_sock_handler(const struct ctx *c, union epoll_ref ref); void icmpv6_sock_handler(const struct ctx *c, union epoll_ref ref); -int icmp_tap_handler(const struct ctx *c, int af, const void *addr, +int icmp_tap_handler(const struct ctx *c, + int af, const void *saddr, const void *daddr, const struct pool *p, const struct timespec *now); void icmp_timer(const struct ctx *c, const struct timespec *ts); void icmp_init(void); diff --git a/tap.c b/tap.c index 6a14692..4ed63f1 100644 --- a/tap.c +++ b/tap.c @@ -643,7 +643,8 @@ resume: tap_packet_debug(iph, NULL, NULL, 0, NULL, 1); packet_add(pkt, l4_len, l4h); - icmp_tap_handler(c, AF_INET, &iph->daddr, pkt, now); + icmp_tap_handler(c, AF_INET, &iph->saddr, &iph->daddr, + pkt, now); continue; } @@ -708,7 +709,6 @@ append: for (j = 0, seq = tap4_l4; j < seq_count; j++, seq++) { struct pool *p = (struct pool *)&seq->p; - struct in_addr *da = &seq->daddr; size_t n = p->count; tap_packet_debug(NULL, NULL, seq, 0, NULL, n); @@ -716,11 +716,13 @@ append: if (seq->protocol == IPPROTO_TCP) { if (c->no_tcp) continue; - while ((n -= tcp_tap_handler(c, AF_INET, da, p, now))); + while ((n -= tcp_tap_handler(c, AF_INET, &seq->saddr, + &seq->daddr, p, now))); } else if (seq->protocol == IPPROTO_UDP) { if (c->no_udp) continue; - while ((n -= udp_tap_handler(c, AF_INET, da, p, now))); + while ((n -= udp_tap_handler(c, AF_INET, &seq->saddr, + &seq->daddr, p, now))); } } @@ -801,7 +803,7 @@ resume: tap_packet_debug(NULL, ip6h, NULL, proto, NULL, 1); packet_add(pkt, l4_len, l4h); - icmp_tap_handler(c, AF_INET6, daddr, pkt, now); + icmp_tap_handler(c, AF_INET6, saddr, daddr, pkt, now); continue; } @@ -868,7 +870,6 @@ append: for (j = 0, seq = tap6_l4; j < seq_count; j++, seq++) { struct pool *p = (struct pool *)&seq->p; - struct in6_addr *da = &seq->daddr; size_t n = p->count; tap_packet_debug(NULL, NULL, NULL, seq->protocol, seq, n); @@ -876,11 +877,13 @@ append: if (seq->protocol == IPPROTO_TCP) { if (c->no_tcp) continue; - while ((n -= tcp_tap_handler(c, AF_INET6, da, p, now))); + while ((n -= tcp_tap_handler(c, AF_INET6, &seq->saddr, + &seq->daddr, p, now))); } else if (seq->protocol == IPPROTO_UDP) { if (c->no_udp) continue; - while ((n -= udp_tap_handler(c, AF_INET6, da, p, now))); + while ((n -= udp_tap_handler(c, AF_INET6, &seq->saddr, + &seq->daddr, p, now))); } } diff --git a/tcp.c b/tcp.c index 0322842..68141e9 100644 --- a/tcp.c +++ b/tcp.c @@ -2005,13 +2005,15 @@ static void tcp_bind_outbound(const struct ctx *c, int s, sa_family_t af) * tcp_conn_from_tap() - Handle connection request (SYN segment) from tap * @c: Execution context * @af: Address family, AF_INET or AF_INET6 - * @addr: Remote address, pointer to in_addr or in6_addr + * @saddr: Source address, pointer to in_addr or in6_addr + * @daddr: Destination address, pointer to in_addr or in6_addr * @th: TCP header from tap: caller MUST ensure it's there * @opts: Pointer to start of options * @optlen: Bytes in options: caller MUST ensure available length * @now: Current timestamp */ -static void tcp_conn_from_tap(struct ctx *c, int af, const void *addr, +static void tcp_conn_from_tap(struct ctx *c, + int af, const void *saddr, const void *daddr, const struct tcphdr *th, const char *opts, size_t optlen, const struct timespec *now) { @@ -2019,18 +2021,20 @@ static void tcp_conn_from_tap(struct ctx *c, int af, const void *addr, struct sockaddr_in addr4 = { .sin_family = AF_INET, .sin_port = th->dest, - .sin_addr = *(struct in_addr *)addr, + .sin_addr = *(struct in_addr *)daddr, }; struct sockaddr_in6 addr6 = { .sin6_family = AF_INET6, .sin6_port = th->dest, - .sin6_addr = *(struct in6_addr *)addr, + .sin6_addr = *(struct in6_addr *)daddr, }; const struct sockaddr *sa; struct tcp_tap_conn *conn; socklen_t sl; int s, mss; + (void)saddr; + if (c->tcp.conn_count >= TCP_MAX_CONNS) return; @@ -2039,9 +2043,9 @@ static void tcp_conn_from_tap(struct ctx *c, int af, const void *addr, return; if (!c->no_map_gw) { - if (af == AF_INET && IN4_ARE_ADDR_EQUAL(addr, &c->ip4.gw)) + if (af == AF_INET && IN4_ARE_ADDR_EQUAL(daddr, &c->ip4.gw)) addr4.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - if (af == AF_INET6 && IN6_ARE_ADDR_EQUAL(addr, &c->ip6.gw)) + if (af == AF_INET6 && IN6_ARE_ADDR_EQUAL(daddr, &c->ip6.gw)) addr6.sin6_addr = in6addr_loopback; } @@ -2078,7 +2082,7 @@ static void tcp_conn_from_tap(struct ctx *c, int af, const void *addr, if (!(conn->wnd_from_tap = (htons(th->window) >> conn->ws_from_tap))) conn->wnd_from_tap = 1; - inany_from_af(&conn->addr, af, addr); + inany_from_af(&conn->addr, af, daddr); if (af == AF_INET) { sa = (struct sockaddr *)&addr4; @@ -2556,13 +2560,14 @@ static void tcp_conn_from_sock_finish(struct ctx *c, struct tcp_tap_conn *conn, * tcp_tap_handler() - Handle packets from tap and state transitions * @c: Execution context * @af: Address family, AF_INET or AF_INET6 - * @addr: Destination address + * @saddr: Source address + * @daddr: Destination address * @p: Pool of TCP packets, with TCP headers * @now: Current timestamp * * Return: count of consumed packets */ -int tcp_tap_handler(struct ctx *c, int af, const void *addr, +int tcp_tap_handler(struct ctx *c, int af, const void *saddr, const void *daddr, const struct pool *p, const struct timespec *now) { struct tcp_tap_conn *conn; @@ -2583,12 +2588,13 @@ int tcp_tap_handler(struct ctx *c, int af, const void *addr, optlen = MIN(optlen, ((1UL << 4) /* from doff width */ - 6) * 4UL); opts = packet_get(p, 0, sizeof(*th), optlen, NULL); - conn = tcp_hash_lookup(c, af, addr, htons(th->source), htons(th->dest)); + conn = tcp_hash_lookup(c, af, daddr, htons(th->source), htons(th->dest)); /* New connection from tap */ if (!conn) { if (opts && th->syn && !th->ack) - tcp_conn_from_tap(c, af, addr, th, opts, optlen, now); + tcp_conn_from_tap(c, af, saddr, daddr, th, + opts, optlen, now); return 1; } diff --git a/tcp.h b/tcp.h index be296ec..3454d9a 100644 --- a/tcp.h +++ b/tcp.h @@ -17,7 +17,7 @@ void tcp_timer_handler(struct ctx *c, union epoll_ref ref); void tcp_listen_handler(struct ctx *c, union epoll_ref ref, const struct timespec *now); void tcp_sock_handler(struct ctx *c, union epoll_ref ref, uint32_t events); -int tcp_tap_handler(struct ctx *c, int af, const void *addr, +int tcp_tap_handler(struct ctx *c, int af, const void *saddr, const void *daddr, const struct pool *p, const struct timespec *now); int tcp_sock_init(const struct ctx *c, sa_family_t af, const void *addr, const char *ifname, in_port_t port); diff --git a/udp.c b/udp.c index 138e7ab..21c6888 100644 --- a/udp.c +++ b/udp.c @@ -799,7 +799,8 @@ void udp_sock_handler(struct ctx *c, union epoll_ref ref, uint32_t events, * udp_tap_handler() - Handle packets from tap * @c: Execution context * @af: Address family, AF_INET or AF_INET6 - * @addr: Destination address + * @saddr: Source address + * @daddr: Destination address * @p: Pool of UDP packets, with UDP headers * @now: Current timestamp * @@ -807,7 +808,7 @@ void udp_sock_handler(struct ctx *c, union epoll_ref ref, uint32_t events, * * #syscalls sendmmsg */ -int udp_tap_handler(struct ctx *c, int af, const void *addr, +int udp_tap_handler(struct ctx *c, int af, const void *saddr, const void *daddr, const struct pool *p, const struct timespec *now) { struct mmsghdr mm[UIO_MAXIOV]; @@ -821,6 +822,7 @@ int udp_tap_handler(struct ctx *c, int af, const void *addr, socklen_t sl; (void)c; + (void)saddr; uh = packet_get(p, 0, 0, sizeof(*uh), NULL); if (!uh) @@ -836,7 +838,7 @@ int udp_tap_handler(struct ctx *c, int af, const void *addr, s_in = (struct sockaddr_in) { .sin_family = AF_INET, .sin_port = uh->dest, - .sin_addr = *(struct in_addr *)addr, + .sin_addr = *(struct in_addr *)daddr, }; sa = (struct sockaddr *)&s_in; @@ -881,17 +883,17 @@ int udp_tap_handler(struct ctx *c, int af, const void *addr, s_in6 = (struct sockaddr_in6) { .sin6_family = AF_INET6, .sin6_port = uh->dest, - .sin6_addr = *(struct in6_addr *)addr, + .sin6_addr = *(struct in6_addr *)daddr, }; const struct in6_addr *bind_addr = &in6addr_any; sa = (struct sockaddr *)&s_in6; sl = sizeof(s_in6); - if (IN6_ARE_ADDR_EQUAL(addr, &c->ip6.dns_match) && + if (IN6_ARE_ADDR_EQUAL(daddr, &c->ip6.dns_match) && ntohs(s_in6.sin6_port) == 53) { s_in6.sin6_addr = c->ip6.dns_host; - } else if (IN6_ARE_ADDR_EQUAL(addr, &c->ip6.gw) && + } else if (IN6_ARE_ADDR_EQUAL(daddr, &c->ip6.gw) && !c->no_map_gw) { if (!(udp_tap_map[V6][dst].flags & PORT_LOCAL) || (udp_tap_map[V6][dst].flags & PORT_LOOPBACK)) diff --git a/udp.h b/udp.h index 56bcd78..f9d4459 100644 --- a/udp.h +++ b/udp.h @@ -10,7 +10,7 @@ void udp_sock_handler(struct ctx *c, union epoll_ref ref, uint32_t events, const struct timespec *now); -int udp_tap_handler(struct ctx *c, int af, const void *addr, +int udp_tap_handler(struct ctx *c, int af, const void *saddr, const void *daddr, const struct pool *p, const struct timespec *now); int udp_sock_init(const struct ctx *c, int ns, sa_family_t af, const void *addr, const char *ifname, in_port_t port);