/**
* IP TTL we use for packets that we assemble (8 bit unsigned integer)
*/
-#define FRESH_TTL 255
+#define FRESH_TTL 64
/**
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->diff_serv = 0;
ip->total_length = htons (sizeof (struct GNUNET_TUN_IPv4Header) + payload_length);
ip->identification = (uint16_t) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
65536);
- ip->flags = 0;
- ip->fragmentation_offset = 0;
ip->ttl = FRESH_TTL;
ip->protocol = protocol;
- ip->checksum = 0;
ip->source_address = *src;
ip->destination_address = *dst;
ip->checksum = GNUNET_CRYPTO_crc16_n (ip, sizeof (struct GNUNET_TUN_IPv4Header));
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));
- ip->traffic_class_h = 0;
+ memset (ip, 0, sizeof (struct GNUNET_TUN_IPv6Header));
ip->version = 6;
- ip->traffic_class_l = 0;
- ip->flow_label = 0;
ip->next_header = protocol;
- ip->payload_length = htons ((uint16_t) (payload_length + sizeof (struct GNUNET_TUN_IPv6Header)));
+ ip->payload_length = htons ((uint16_t) payload_length);
ip->hop_limit = FRESH_TTL;
ip->destination_address = *dst;
ip->source_address = *src;
/**
* Calculate IPv4 TCP checksum.
*
- * @param ipv4 header fully initialized
+ * @param ip ipv4 header fully initialized
* @param tcp TCP header (initialized except for CRC)
* @param payload the TCP payload
* @param payload_length number of bytes of TCP payload
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);
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);
/**
* Calculate IPv6 TCP checksum.
*
- * @param ipv6 header fully initialized
+ * @param ip ipv6 header fully initialized
* @param tcp header (initialized except for CRC)
* @param payload the TCP payload
* @param payload_length number of bytes of TCP payload
uint32_t sum;
uint32_t tmp;
- GNUNET_assert (payload_length + sizeof (struct GNUNET_TUN_IPv6Header) + sizeof (struct GNUNET_TUN_TcpHeader) ==
+ 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);
tcp->crc = 0;
/**
* Calculate IPv4 UDP checksum.
*
- * @param ipv4 header fully initialized
+ * @param ip ipv4 header fully initialized
* @param udp UDP header (initialized except for CRC)
* @param payload the UDP payload
* @param payload_length number of bytes of UDP payload
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);
/**
* Calculate IPv6 UDP checksum.
*
- * @param ipv6 header fully initialized
+ * @param ip ipv6 header fully initialized
* @param udp UDP header (initialized except for CRC)
* @param payload the UDP payload
* @param payload_length number of bytes of UDP payload
uint32_t sum;
uint32_t tmp;
- GNUNET_assert (payload_length + sizeof (struct GNUNET_TUN_IPv6Header) + sizeof (struct GNUNET_TUN_UdpHeader) ==
+ GNUNET_assert (payload_length + sizeof (struct GNUNET_TUN_UdpHeader) ==
ntohs (ip->payload_length));
GNUNET_assert (payload_length + sizeof (struct GNUNET_TUN_UdpHeader) ==
ntohs (udp->len));
}
+/**
+ * Calculate ICMP checksum.
+ *
+ * @param icmp IMCP header (initialized except for CRC)
+ * @param payload the ICMP payload
+ * @param payload_length number of bytes of ICMP payload
+ */
+void
+GNUNET_TUN_calculate_icmp_checksum (struct GNUNET_TUN_IcmpHeader *icmp,
+ const void *payload,
+ uint16_t payload_length)
+{
+ uint32_t sum;
+
+ GNUNET_assert (8 == sizeof (struct GNUNET_TUN_IcmpHeader));
+ icmp->crc = 0;
+ sum = GNUNET_CRYPTO_crc16_step (0,
+ icmp,
+ sizeof (struct GNUNET_TUN_IcmpHeader));
+ sum = GNUNET_CRYPTO_crc16_step (sum, payload, payload_length);
+ icmp->crc = GNUNET_CRYPTO_crc16_finish (sum);
+}
+
+
/* end of tun.c */