Decrement TTL of incoming packets.
Tinc will now, by default, decrement the TTL field of incoming IPv4 and IPv6 packets, before forwarding them to the virtual network device or to another node. Packets with a TTL value of zero will be dropped, and an ICMP Time Exceeded message will be sent back. This behaviour can be disabled using the DecrementTTL option.
This commit is contained in:
parent
6289859ab3
commit
0233b1d710
5 changed files with 67 additions and 0 deletions
|
|
@ -398,6 +398,8 @@ static bool setup_myself(void) {
|
|||
|
||||
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");
|
||||
|
|
|
|||
49
src/route.c
49
src/route.c
|
|
@ -34,6 +34,7 @@
|
|||
|
||||
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;
|
||||
|
|
@ -846,6 +847,50 @@ static void route_mac(node_t *source, vpn_packet_t *packet) {
|
|||
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);
|
||||
|
|
@ -855,6 +900,10 @@ void route(node_t *source, vpn_packet_t *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:
|
||||
{
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ typedef enum fmode_t {
|
|||
|
||||
extern rmode_t routing_mode;
|
||||
extern fmode_t forwarding_mode;
|
||||
extern bool decrement_ttl;
|
||||
extern bool directonly;
|
||||
extern bool overwrite_mac;
|
||||
extern bool priorityinheritance;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue