diff options
author | Tobias Brunner <tobias@strongswan.org> | 2015-11-02 16:16:56 +0100 |
---|---|---|
committer | Tobias Brunner <tobias@strongswan.org> | 2015-11-09 16:42:20 +0100 |
commit | 99747bed8f0aea9427bd17820dbde79342bb9ce9 (patch) | |
tree | 5f5b3e7ffd792b8640fcad72dc2ac2416804fa07 /src/libcharon/plugins/socket_default/socket_default_socket.c | |
parent | 9953e76c3dc7de15a4024946820ea2d8b90ed996 (diff) | |
download | strongswan-99747bed8f0aea9427bd17820dbde79342bb9ce9.tar.bz2 strongswan-99747bed8f0aea9427bd17820dbde79342bb9ce9.tar.xz |
socket-default: Refactor retrieval of destination address of received packets
This makes the code a bit clearer than with the interleaved ifdefs.
Diffstat (limited to 'src/libcharon/plugins/socket_default/socket_default_socket.c')
-rw-r--r-- | src/libcharon/plugins/socket_default/socket_default_socket.c | 128 |
1 files changed, 89 insertions, 39 deletions
diff --git a/src/libcharon/plugins/socket_default/socket_default_socket.c b/src/libcharon/plugins/socket_default/socket_default_socket.c index dbfddbb81..421593cac 100644 --- a/src/libcharon/plugins/socket_default/socket_default_socket.c +++ b/src/libcharon/plugins/socket_default/socket_default_socket.c @@ -148,6 +148,91 @@ struct private_socket_default_socket_t { u_int rr_counter; }; +/** + * Get the destination IPv4 address of a received packet, depending on the + * available mechanism. + */ +#ifdef IP_PKTINFO + +static host_t *get_dst_v4(struct cmsghdr *cmsgptr, u_int16_t port) +{ + struct sockaddr_in dst = { + .sin_family = AF_INET, + .sin_port = htons(port), + }; + struct in_pktinfo *pktinfo; + struct in_addr *addr; + + if (cmsgptr->cmsg_type == IP_PKTINFO) + { + pktinfo = (struct in_pktinfo*)CMSG_DATA(cmsgptr); + addr = &pktinfo->ipi_addr; + memcpy(&dst.sin_addr, addr, sizeof(dst.sin_addr)); + return host_create_from_sockaddr((sockaddr_t*)&dst); + } + return NULL; +} + +#elif defined(IP_RECVDSTADDR) + +static host_t *get_dst_v4(struct cmsghdr *cmsgptr, u_int16_t port) +{ + struct sockaddr_in dst = { + .sin_family = AF_INET, + .sin_port = htons(port), + }; + struct in_addr *addr; + + if (cmsgptr->cmsg_type == IP_RECVDSTADDR) + { + addr = (struct in_addr*)CMSG_DATA(cmsgptr); + memcpy(&dst.sin_addr, addr, sizeof(dst.sin_addr)); + return host_create_from_sockaddr((sockaddr_t*)&dst); + } + return NULL; +} + +#else /* IP_PKTINFO || IP_RECVDSTADDR */ + +static host_t *get_dst_v4(struct cmsghdr *cmsgptr, u_int16_t port) +{ + return NULL; +} + +#endif /* IP_PKTINFO || IP_RECVDSTADDR */ + +/** + * Get the destination IPv6 address of a received packet, depending on the + * available mechanism. + */ +#ifdef HAVE_IN6_PKTINFO + +static host_t *get_dst_v6(struct cmsghdr *cmsgptr, u_int16_t port) +{ + struct in6_pktinfo *pktinfo; + struct sockaddr_in6 dst = { + .sin6_family = AF_INET6, + .sin6_port = htons(port), + }; + + if (cmsgptr->cmsg_type == IPV6_PKTINFO) + { + pktinfo = (struct in6_pktinfo*)CMSG_DATA(cmsgptr); + memcpy(&dst.sin6_addr, &pktinfo->ipi6_addr, sizeof(dst.sin6_addr)); + return host_create_from_sockaddr((sockaddr_t*)&dst); + } + return NULL; +} + +#else /* HAVE_IN6_PKTINFO */ + +static host_t *get_dst_v6(struct cmsghdr *cmsgptr, u_int16_t port) +{ + return NULL; +} + +#endif /* HAVE_IN6_PKTINFO */ + METHOD(socket_t, receiver, status_t, private_socket_default_socket_t *this, packet_t **packet) { @@ -233,48 +318,13 @@ METHOD(socket_t, receiver, status_t, DBG1(DBG_NET, "error reading ancillary data"); return FAILED; } - -#ifdef HAVE_IN6_PKTINFO - if (cmsgptr->cmsg_level == SOL_IPV6 && - cmsgptr->cmsg_type == IPV6_PKTINFO) + if (cmsgptr->cmsg_level == SOL_IP) { - struct in6_pktinfo *pktinfo; - pktinfo = (struct in6_pktinfo*)CMSG_DATA(cmsgptr); - struct sockaddr_in6 dst; - - memset(&dst, 0, sizeof(dst)); - memcpy(&dst.sin6_addr, &pktinfo->ipi6_addr, sizeof(dst.sin6_addr)); - dst.sin6_family = AF_INET6; - dst.sin6_port = htons(port); - dest = host_create_from_sockaddr((sockaddr_t*)&dst); + dest = get_dst_v4(cmsgptr, port); } -#endif /* HAVE_IN6_PKTINFO */ - if (cmsgptr->cmsg_level == SOL_IP && -#ifdef IP_PKTINFO - cmsgptr->cmsg_type == IP_PKTINFO -#elif defined(IP_RECVDSTADDR) - cmsgptr->cmsg_type == IP_RECVDSTADDR -#else - FALSE -#endif - ) + else if (cmsgptr->cmsg_level == SOL_IPV6) { - struct in_addr *addr; - struct sockaddr_in dst; - -#ifdef IP_PKTINFO - struct in_pktinfo *pktinfo; - pktinfo = (struct in_pktinfo*)CMSG_DATA(cmsgptr); - addr = &pktinfo->ipi_addr; -#elif defined(IP_RECVDSTADDR) - addr = (struct in_addr*)CMSG_DATA(cmsgptr); -#endif - memset(&dst, 0, sizeof(dst)); - memcpy(&dst.sin_addr, addr, sizeof(dst.sin_addr)); - - dst.sin_family = AF_INET; - dst.sin_port = htons(port); - dest = host_create_from_sockaddr((sockaddr_t*)&dst); + dest = get_dst_v6(cmsgptr, port); } if (dest) { |