won't try to connect to other daemons at all,
and will instead just listen for incoming connections.
+.It Va DecrementTTL Li = yes | no Po yes Pc
+When enabled,
+.Nm tinc
+will decrement the Time To Live field in IPv4 packets, or the Hop Limit field in IPv6 packets,
+before forwarding a received packet to the virtual network device or to another node,
+and will drop packets that have a TTL value of zero,
+in which case it will send an ICMP Time Exceeded packet back.
+
.It Va Device Li = Ar device Po Pa /dev/tap0 , Pa /dev/net/tun No or other depending on platform Pc
The virtual network device to use.
.Nm tinc
tinc won't try to connect to other daemons at all,
and will instead just listen for incoming connections.
+@cindex DecrementTTL
+@item DecrementTTL = <yes | no> (yes)
+When enabled, tinc will decrement the Time To Live field in IPv4 packets, or the Hop Limit field in IPv6 packets,
+before forwarding a received packet to the virtual network device or to another node,
+and will drop packets that have a TTL value of zero,
+in which case it will send an ICMP Time Exceeded packet back.
+
@cindex Device
@item Device = <@var{device}> (@file{/dev/tap0}, @file{/dev/net/tun} or other depending on platform)
The virtual network device to use.
get_config_bool(lookup_config(config_tree, "PriorityInheritance"), &priorityinheritance);
+ get_config_bool(lookup_config(config_tree, "DecrementTTL"), &decrement_ttl);
+
#if !defined(SOL_IP) || !defined(IP_TOS)
if(priorityinheritance)
logger(LOG_WARNING, "%s not supported on this platform", "PriorityInheritance");
rmode_t routing_mode = RMODE_ROUTER;
fmode_t forwarding_mode = FMODE_INTERNAL;
+bool decrement_ttl = true;
bool directonly = false;
bool priorityinheritance = false;
int macexpire = 600;
send_packet(subnet->owner, packet);
}
+static bool do_decrement_ttl(node_t *source, vpn_packet_t *packet) {
+ uint16_t type = packet->data[12] << 8 | packet->data[13];
+
+ switch (type) {
+ case ETH_P_IP:
+ if(!checklength(source, packet, 14 + 32))
+ return false;
+
+ if(packet->data[22] < 1) {
+ route_ipv4_unreachable(source, packet, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL);
+ return false;
+ }
+
+ uint16_t old = packet->data[22] << 8 | packet->data[23];
+ packet->data[22]--;
+ uint16_t new = packet->data[22] << 8 | packet->data[23];
+
+ uint32_t checksum = packet->data[24] << 8 | packet->data[25];
+ checksum += old + (~new & 0xFFFF);
+ while(checksum >> 16)
+ checksum = (checksum & 0xFFFF) + (checksum >> 16);
+ packet->data[24] = checksum >> 8;
+ packet->data[25] = checksum & 0xff;
+
+ return true;
+
+ case ETH_P_IPV6:
+ if(!checklength(source, packet, 14 + 40))
+ return false;
+
+ if(packet->data[21] < 1) {
+ route_ipv6_unreachable(source, packet, ICMP6_TIME_EXCEEDED, ICMP6_TIME_EXCEED_TRANSIT);
+ return false;
+ }
+
+ packet->data[21]--;
+
+ return true;
+
+ default:
+ return true;
+ }
+}
+
void route(node_t *source, vpn_packet_t *packet) {
if(forwarding_mode == FMODE_KERNEL && source != myself) {
send_packet(myself, packet);
if(!checklength(source, packet, ether_size))
return;
+ if(decrement_ttl && source != myself)
+ if(!do_decrement_ttl(source, packet))
+ return;
+
switch (routing_mode) {
case RMODE_ROUTER:
{
extern rmode_t routing_mode;
extern fmode_t forwarding_mode;
+extern bool decrement_ttl;
extern bool directonly;
extern bool overwrite_mac;
extern bool priorityinheritance;