/*
This file is part of GNUnet.
- (C) 2010, 2011, 2012 Christian Grothoff
+ Copyright (C) 2010, 2011, 2012 Christian Grothoff
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
You should have received a copy of the GNU General Public License
along with GNUnet; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
*/
/**
const struct in_addr *src,
const struct in_addr *dst)
{
+ GNUNET_assert (20 == sizeof (struct GNUNET_TUN_IPv4Header));
GNUNET_assert (payload_length <= UINT16_MAX - sizeof (struct GNUNET_TUN_IPv4Header));
memset (ip, 0, sizeof (struct GNUNET_TUN_IPv4Header));
ip->header_length = sizeof (struct GNUNET_TUN_IPv4Header) / 4;
ip->version = 4;
ip->total_length = htons (sizeof (struct GNUNET_TUN_IPv4Header) + payload_length);
- ip->identification = (uint16_t) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
+ ip->identification = (uint16_t) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
65536);
ip->ttl = FRESH_TTL;
ip->protocol = protocol;
*
* @param ip header to initialize
* @param protocol protocol to use (i.e. IPPROTO_UDP), technically "next_header" for IPv6
- * @param payload_length number of bytes of payload that follow (excluding IPv4 header)
+ * @param payload_length number of bytes of payload that follow (excluding IPv6 header)
* @param src source IP address to use
* @param dst destination IP address to use
*/
const struct in6_addr *src,
const struct in6_addr *dst)
{
+ GNUNET_assert (40 == sizeof (struct GNUNET_TUN_IPv6Header));
GNUNET_assert (payload_length <= UINT16_MAX - sizeof (struct GNUNET_TUN_IPv6Header));
memset (ip, 0, sizeof (struct GNUNET_TUN_IPv6Header));
ip->version = 6;
ip->payload_length = htons ((uint16_t) payload_length);
ip->hop_limit = FRESH_TTL;
ip->destination_address = *dst;
- ip->source_address = *src;
+ ip->source_address = *src;
}
uint16_t payload_length)
{
uint32_t sum;
- uint32_t tmp;
+ uint16_t tmp;
+ GNUNET_assert (20 == sizeof (struct GNUNET_TUN_TcpHeader));
GNUNET_assert (payload_length + sizeof (struct GNUNET_TUN_IPv4Header) + sizeof (struct GNUNET_TUN_TcpHeader) ==
ntohs (ip->total_length));
GNUNET_assert (IPPROTO_TCP == ip->protocol);
tcp->crc = 0;
- sum = GNUNET_CRYPTO_crc16_step (0,
+ sum = GNUNET_CRYPTO_crc16_step (0,
&ip->source_address,
sizeof (struct in_addr) * 2);
- tmp = htonl ((IPPROTO_TCP << 16) | (payload_length + sizeof (struct GNUNET_TUN_TcpHeader)));
- sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t));
+ tmp = htons (IPPROTO_TCP);
+ sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint16_t));
+ tmp = htons (payload_length + sizeof (struct GNUNET_TUN_TcpHeader));
+ sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint16_t));
sum = GNUNET_CRYPTO_crc16_step (sum, tcp, sizeof (struct GNUNET_TUN_TcpHeader));
sum = GNUNET_CRYPTO_crc16_step (sum, payload, payload_length);
tcp->crc = GNUNET_CRYPTO_crc16_finish (sum);
uint32_t sum;
uint32_t tmp;
+ GNUNET_assert (20 == sizeof (struct GNUNET_TUN_TcpHeader));
GNUNET_assert (payload_length + sizeof (struct GNUNET_TUN_TcpHeader) ==
ntohs (ip->payload_length));
GNUNET_assert (IPPROTO_TCP == ip->next_header);
uint32_t sum;
uint16_t tmp;
+ GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader));
GNUNET_assert (payload_length + sizeof (struct GNUNET_TUN_IPv4Header) + sizeof (struct GNUNET_TUN_UdpHeader) ==
ntohs (ip->total_length));
GNUNET_assert (IPPROTO_UDP == ip->protocol);
udp->crc = 0; /* technically optional, but we calculate it anyway, just to be sure */
- sum = GNUNET_CRYPTO_crc16_step (0,
+ sum = GNUNET_CRYPTO_crc16_step (0,
&ip->source_address,
sizeof (struct in_addr) * 2);
tmp = htons (IPPROTO_UDP);
- sum = GNUNET_CRYPTO_crc16_step (sum,
- &tmp,
+ sum = GNUNET_CRYPTO_crc16_step (sum,
+ &tmp,
sizeof (uint16_t));
tmp = htons (sizeof (struct GNUNET_TUN_UdpHeader) + payload_length);
- sum = GNUNET_CRYPTO_crc16_step (sum,
- &tmp,
+ sum = GNUNET_CRYPTO_crc16_step (sum,
+ &tmp,
sizeof (uint16_t));
- sum = GNUNET_CRYPTO_crc16_step (sum,
- udp,
+ sum = GNUNET_CRYPTO_crc16_step (sum,
+ udp,
sizeof (struct GNUNET_TUN_UdpHeader));
- sum = GNUNET_CRYPTO_crc16_step (sum,
+ sum = GNUNET_CRYPTO_crc16_step (sum,
payload,
payload_length);
udp->crc = GNUNET_CRYPTO_crc16_finish (sum);
{
uint32_t sum;
+ GNUNET_assert (8 == sizeof (struct GNUNET_TUN_IcmpHeader));
icmp->crc = 0;
sum = GNUNET_CRYPTO_crc16_step (0,
icmp,
}
+/**
+ * Check if two sockaddrs are equal.
+ *
+ * @param sa one address
+ * @param sb another address
+ * @param include_port also check ports
+ * @return #GNUNET_YES if they are equal
+ */
+int
+GNUNET_TUN_sockaddr_cmp (const struct sockaddr *sa,
+ const struct sockaddr *sb,
+ int include_port)
+{
+ if (sa->sa_family != sb->sa_family)
+ return GNUNET_NO;
+
+ switch (sa->sa_family)
+ {
+ case AF_INET:
+ {
+ const struct sockaddr_in *sa4 = (const struct sockaddr_in *) sa;
+ const struct sockaddr_in *sb4 = (const struct sockaddr_in *) sb;
+ return (sa4->sin_addr.s_addr == sb4->sin_addr.s_addr);
+ }
+ case AF_INET6:
+ {
+ const struct sockaddr_in6 *sa6 = (const struct sockaddr_in6 *) sa;
+ const struct sockaddr_in6 *sb6 = (const struct sockaddr_in6 *) sb;
+
+ return (0 == memcmp(&sa6->sin6_addr,
+ &sb6->sin6_addr,
+ sizeof (struct in6_addr)));
+ }
+ default:
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+}
+
+
/* end of tun.c */