diff --git a/aggregation.c b/aggregation.c
index 5bd74e1..d9ca9ae 100644
--- a/aggregation.c
+++ b/aggregation.c
@@ -69,7 +69,7 @@ static bool can_aggregate_with(struct batman_packet *new_batman_packet,
 		 * are flooded through the net  */
 		if ((!directlink) &&
 		    (!(batman_packet->flags & DIRECTLINK)) &&
-		    (batman_packet->header.ttl != 1) &&
+		    (batman_packet->header.ttl != 2) &&
 
 		    /* own packets originating non-primary
 		     * interfaces leave only that interface */
@@ -80,7 +80,7 @@ static bool can_aggregate_with(struct batman_packet *new_batman_packet,
 		/* if the incoming packet is sent via this one
 		 * interface only - we still can aggregate */
 		if ((directlink) &&
-		    (new_batman_packet->header.ttl == 1) &&
+		    (new_batman_packet->header.ttl == 2) &&
 		    (forw_packet->if_incoming == if_incoming) &&
 
 		    /* packets from direct neighbors or
diff --git a/hard-interface.c b/hard-interface.c
index 3637602..b0105e9 100644
--- a/hard-interface.c
+++ b/hard-interface.c
@@ -314,7 +314,7 @@ int hardif_enable_interface(struct hard_iface *hard_iface, char *iface_name)
 	batman_packet = (struct batman_packet *)(hard_iface->packet_buff);
 	batman_packet->header.packet_type = BAT_PACKET;
 	batman_packet->header.version = COMPAT_VERSION;
-	batman_packet->header.ttl = 2;
+	batman_packet->header.ttl = 3;
 	batman_packet->flags = 0;
 	batman_packet->tq = TQ_MAX_VALUE;
 	batman_packet->num_hna = 0;
diff --git a/routing.c b/routing.c
index 115a8de..c60296c 100644
--- a/routing.c
+++ b/routing.c
@@ -930,73 +930,6 @@ out:
 	return ret;
 }
 
-static int recv_icmp_ttl_exceeded(struct bat_priv *bat_priv,
-				  struct sk_buff *skb)
-{
-	struct orig_node *orig_node = NULL;
-	struct neigh_node *neigh_node = NULL;
-	struct icmp_packet *icmp_packet;
-	int ret = NET_RX_DROP;
-
-	icmp_packet = (struct icmp_packet *)skb->data;
-
-	/* send TTL exceeded if packet is an echo request (traceroute) */
-	if (icmp_packet->msg_type != ECHO_REQUEST) {
-		pr_debug("Warning - can't forward icmp packet from %pM to "
-			 "%pM: ttl exceeded\n", icmp_packet->orig,
-			 icmp_packet->dst);
-		goto out;
-	}
-
-	if (!bat_priv->primary_if)
-		goto out;
-
-	/* get routing information */
-	rcu_read_lock();
-	orig_node = orig_hash_find(bat_priv, icmp_packet->orig);
-
-	if (!orig_node)
-		goto unlock;
-
-	neigh_node = orig_node->router;
-
-	if (!neigh_node)
-		goto unlock;
-
-	if (!atomic_inc_not_zero(&neigh_node->refcount)) {
-		neigh_node = NULL;
-		goto unlock;
-	}
-
-	rcu_read_unlock();
-
-	/* create a copy of the skb, if needed, to modify it. */
-	if (skb_cow(skb, sizeof(struct ethhdr)) < 0)
-		goto out;
-
-	icmp_packet = (struct icmp_packet *)skb->data;
-
-	memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN);
-	memcpy(icmp_packet->orig,
-		bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
-	icmp_packet->msg_type = TTL_EXCEEDED;
-	icmp_packet->header.ttl = TTL;
-
-	send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
-	ret = NET_RX_SUCCESS;
-	goto out;
-
-unlock:
-	rcu_read_unlock();
-out:
-	if (neigh_node)
-		neigh_node_free_ref(neigh_node);
-	if (orig_node)
-		orig_node_free_ref(orig_node);
-	return ret;
-}
-
-
 int recv_icmp_packet(struct sk_buff *skb, struct hard_iface *recv_if)
 {
 	struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface);
@@ -1045,10 +978,6 @@ int recv_icmp_packet(struct sk_buff *skb, struct hard_iface *recv_if)
 	if (is_my_mac(icmp_packet->dst))
 		return recv_my_icmp_packet(bat_priv, skb, hdr_size);
 
-	/* TTL exceeded */
-	if (icmp_packet->header.ttl < 2)
-		return recv_icmp_ttl_exceeded(bat_priv, skb);
-
 	/* get routing information */
 	rcu_read_lock();
 	orig_node = orig_hash_find(bat_priv, icmp_packet->dst);
@@ -1074,9 +1003,6 @@ int recv_icmp_packet(struct sk_buff *skb, struct hard_iface *recv_if)
 
 	icmp_packet = (struct icmp_packet_rr *)skb->data;
 
-	/* decrement ttl */
-	icmp_packet->header.ttl--;
-
 	/* route it */
 	send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
 	ret = NET_RX_SUCCESS;
@@ -1269,20 +1195,11 @@ int route_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if)
 	struct orig_node *orig_node = NULL;
 	struct neigh_node *neigh_node = NULL;
 	struct unicast_packet *unicast_packet;
-	struct ethhdr *ethhdr = (struct ethhdr *)skb_mac_header(skb);
 	int ret = NET_RX_DROP;
 	struct sk_buff *new_skb;
 
 	unicast_packet = (struct unicast_packet *)skb->data;
 
-	/* TTL exceeded */
-	if (unicast_packet->header.ttl < 2) {
-		pr_debug("Warning - can't forward unicast packet from %pM to "
-			 "%pM: ttl exceeded\n", ethhdr->h_source,
-			 unicast_packet->dest);
-		goto out;
-	}
-
 	/* get routing information */
 	rcu_read_lock();
 	orig_node = orig_hash_find(bat_priv, unicast_packet->dest);
@@ -1327,12 +1244,8 @@ int route_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if)
 		}
 
 		skb = new_skb;
-		unicast_packet = (struct unicast_packet *)skb->data;
 	}
 
-	/* decrement ttl */
-	unicast_packet->header.ttl--;
-
 	/* route it */
 	send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
 	ret = NET_RX_SUCCESS;
@@ -1435,9 +1348,6 @@ int recv_bcast_packet(struct sk_buff *skb, struct hard_iface *recv_if)
 	if (is_my_mac(bcast_packet->orig))
 		goto out;
 
-	if (bcast_packet->header.ttl < 2)
-		goto out;
-
 	rcu_read_lock();
 	orig_node = orig_hash_find(bat_priv, bcast_packet->orig);
 
diff --git a/send.c b/send.c
index 93e4f8f..1f1afce 100644
--- a/send.c
+++ b/send.c
@@ -22,6 +22,7 @@
 #include "main.h"
 #include "send.h"
 #include "routing.h"
+#include "hash.h"
 #include "translation-table.h"
 #include "soft-interface.h"
 #include "hard-interface.h"
@@ -53,13 +54,105 @@ static unsigned long forward_send_time(void)
 	return jiffies + msecs_to_jiffies(random32() % (JITTER/2));
 }
 
+static int send_icmp_ttl_exceeded(struct bat_priv *bat_priv,
+				  struct sk_buff *skb)
+{
+	struct orig_node *orig_node = NULL;
+	struct neigh_node *neigh_node = NULL;
+	struct icmp_packet *icmp_packet;
+	int ret = NET_RX_DROP;
+
+	icmp_packet = (struct icmp_packet *)skb->data;
+
+	/* send TTL exceeded if packet is an echo request (traceroute) */
+	if (icmp_packet->msg_type != ECHO_REQUEST) {
+		pr_debug("Warning - can't forward icmp packet from %pM to "
+			 "%pM: ttl exceeded\n", icmp_packet->orig,
+			 icmp_packet->dst);
+		goto out;
+	}
+
+	if (!bat_priv->primary_if)
+		goto out;
+
+	/* get routing information */
+	rcu_read_lock();
+	orig_node = orig_hash_find(bat_priv, icmp_packet->orig);
+
+	if (!orig_node)
+		goto unlock;
+
+	neigh_node = orig_node->router;
+
+	if (!neigh_node)
+		goto unlock;
+
+	if (!atomic_inc_not_zero(&neigh_node->refcount)) {
+		neigh_node = NULL;
+		goto unlock;
+	}
+
+	rcu_read_unlock();
+
+	/* create a copy of the skb, if needed, to modify it. */
+	if (skb_cow(skb, sizeof(struct ethhdr)) < 0)
+		goto out;
+
+	icmp_packet = (struct icmp_packet *)skb->data;
+
+	memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN);
+	memcpy(icmp_packet->orig,
+		bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
+	icmp_packet->msg_type = TTL_EXCEEDED;
+	icmp_packet->header.ttl = TTL;
+
+	send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
+	ret = NET_RX_SUCCESS;
+	goto out;
+
+unlock:
+	rcu_read_unlock();
+out:
+	if (neigh_node)
+		neigh_node_free_ref(neigh_node);
+	if (orig_node)
+		orig_node_free_ref(orig_node);
+	return ret;
+}
+
+static void print_ttl_exceeded(struct sk_buff *skb, int packet_type,
+			       struct bat_priv *bat_priv) {
+	switch (packet_type) {
+	case BAT_PACKET:
+		bat_dbg(DBG_BATMAN, bat_priv, "ttl exceeded\n");
+		break;
+	case BAT_ICMP:
+		send_icmp_ttl_exceeded(bat_priv, skb);
+		break;
+	case BAT_VIS:
+		pr_debug("Error - can't send vis packet: ttl exceeded\n");
+		break;
+	case BAT_UNICAST:
+		pr_debug("Warning - can't forward unicast packet from %pM to "
+			 "%pM: ttl exceeded\n",
+			 ((struct ethhdr *)skb->data)->h_source,
+			 ((struct unicast_packet *)skb->data)->dest);
+		break;
+	default:
+		break;
+	}
+}
+
 /* send out an already prepared packet to the given address via the
- * specified batman interface */
+ * specified batman interface; drops it if the current TTL is 1 or less
+ * or else reduces the TTL by one */
 int send_skb_packet(struct sk_buff *skb,
 				struct hard_iface *hard_iface,
 				uint8_t *dst_addr)
 {
 	struct ethhdr *ethhdr;
+	struct batman_header *batman_header;
+	struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
 
 	if (hard_iface->if_status != IF_ACTIVE)
 		goto send_skb_err;
@@ -73,6 +166,15 @@ int send_skb_packet(struct sk_buff *skb,
 		goto send_skb_err;
 	}
 
+	if (unlikely(!pskb_may_pull(skb, sizeof(struct batman_packet))))
+		goto send_skb_err;
+	batman_header = (struct batman_header *) skb->data;
+	if (batman_header->ttl <= 1) {
+		print_ttl_exceeded(skb, batman_header->packet_type, bat_priv);
+		goto send_skb_err;
+	}
+	batman_header->ttl--;
+
 	/* push to the ethernet header. */
 	if (my_skb_head_push(skb, sizeof(struct ethhdr)) < 0)
 		goto send_skb_err;
@@ -182,7 +284,7 @@ static void send_packet(struct forw_packet *forw_packet)
 
 	/* multihomed peer assumed */
 	/* non-primary OGMs are only broadcasted on their interface */
-	if ((directlink && (batman_packet->header.ttl == 1)) ||
+	if ((directlink && (batman_packet->header.ttl == 2)) ||
 	    (forw_packet->own && (forw_packet->if_incoming->if_num > 0))) {
 
 		/* FIXME: what about aggregated packets ? */
@@ -311,15 +413,9 @@ void schedule_forward_packet(struct orig_node *orig_node,
 	unsigned char in_tq, in_ttl, tq_avg = 0;
 	unsigned long send_time;
 
-	if (batman_packet->header.ttl <= 1) {
-		bat_dbg(DBG_BATMAN, bat_priv, "ttl exceeded\n");
-		return;
-	}
-
 	in_tq = batman_packet->tq;
 	in_ttl = batman_packet->header.ttl;
 
-	batman_packet->header.ttl--;
 	memcpy(batman_packet->prev_sender, ethhdr->h_source, ETH_ALEN);
 
 	/* rebroadcast tq of our best ranking neighbor to ensure the rebroadcast
@@ -332,7 +428,7 @@ void schedule_forward_packet(struct orig_node *orig_node,
 
 			if (orig_node->router->last_ttl)
 				batman_packet->header.ttl =
-					orig_node->router->last_ttl - 1;
+						orig_node->router->last_ttl;
 		}
 
 		tq_avg = orig_node->router->tq_avg;
@@ -344,8 +440,8 @@ void schedule_forward_packet(struct orig_node *orig_node,
 	bat_dbg(DBG_BATMAN, bat_priv,
 		"Forwarding packet: tq_orig: %i, tq_avg: %i, "
 		"tq_forw: %i, ttl_orig: %i, ttl_forw: %i\n",
-		in_tq, tq_avg, batman_packet->tq, in_ttl - 1,
-		batman_packet->header.ttl);
+		in_tq, tq_avg, batman_packet->tq, in_ttl,
+		batman_packet->header.ttl - 1);
 
 	batman_packet->seqno = htonl(batman_packet->seqno);
 
@@ -400,7 +496,6 @@ static void _add_bcast_packet_to_list(struct bat_priv *bat_priv,
 int add_bcast_packet_to_list(struct bat_priv *bat_priv, struct sk_buff *skb)
 {
 	struct forw_packet *forw_packet;
-	struct bcast_packet *bcast_packet;
 
 	if (!atomic_dec_not_zero(&bat_priv->bcast_queue_left)) {
 		bat_dbg(DBG_BATMAN, bat_priv, "bcast packet queue full\n");
@@ -419,10 +514,6 @@ int add_bcast_packet_to_list(struct bat_priv *bat_priv, struct sk_buff *skb)
 	if (!skb)
 		goto packet_free;
 
-	/* as we have a copy now, it is safe to decrease the TTL */
-	bcast_packet = (struct bcast_packet *)skb->data;
-	bcast_packet->header.ttl--;
-
 	skb_reset_mac_header(skb);
 
 	forw_packet->skb = skb;
diff --git a/unicast.c b/unicast.c
index a57033a..2677c06 100644
--- a/unicast.c
+++ b/unicast.c
@@ -250,7 +250,6 @@ int frag_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv,
 
 	memcpy(frag1, &tmp_uc, sizeof(struct unicast_packet));
 
-	frag1->header.ttl--;
 	frag1->header.version = COMPAT_VERSION;
 	frag1->header.packet_type = BAT_UNICAST_FRAG;
 
@@ -327,8 +326,6 @@ find_router:
 	if (atomic_read(&bat_priv->fragmentation) &&
 	    data_len + sizeof(struct unicast_packet) >
 				neigh_node->if_incoming->net_dev->mtu) {
-		/* send frag skb decreases ttl */
-		unicast_packet->header.ttl++;
 		ret = frag_send_skb(skb, bat_priv,
 				    neigh_node->if_incoming, neigh_node->addr);
 		goto out;
diff --git a/vis.c b/vis.c
index 491430c..cde91f4 100644
--- a/vis.c
+++ b/vis.c
@@ -819,20 +819,14 @@ static void send_vis_packet(struct bat_priv *bat_priv, struct vis_info *info)
 	struct vis_packet *packet;
 
 	packet = (struct vis_packet *)info->skb_packet->data;
-	if (packet->header.ttl < 2) {
-		pr_debug("Error - can't send vis packet: ttl exceeded\n");
-		return;
-	}
 
 	memcpy(packet->sender_orig, bat_priv->primary_if->net_dev->dev_addr,
 	       ETH_ALEN);
-	packet->header.ttl--;
 
 	if (is_broadcast_ether_addr(packet->target_orig))
 		broadcast_vis_packet(bat_priv, info);
 	else
 		unicast_vis_packet(bat_priv, info);
-	packet->header.ttl++; /* restore TTL */
 }
 
 /* called from timer; send (and maybe generate) vis packet. */
