aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2020-11-27 23:12:20 +0000
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2020-11-27 23:12:20 +0000
commit20a37bd70d20bad34ad6a05f360771e00ae301ec (patch)
treee2703457d3dfc3c83d3b7b9d5084f988b44761e8
parent65a228860cea416477aa5887f1e3601f607baf00 (diff)
parent5c1c9d43be61571608e9b14615045b67b830daf5 (diff)
downloadslirp-20a37bd70d20bad34ad6a05f360771e00ae301ec.zip
slirp-20a37bd70d20bad34ad6a05f360771e00ae301ec.tar.gz
slirp-20a37bd70d20bad34ad6a05f360771e00ae301ec.tar.bz2
Merge branch 'ttl' into 'master'
udp, udp6, icmp: handle TTL value See merge request slirp/libslirp!48
-rw-r--r--src/ip_icmp.c15
-rw-r--r--src/udp.c15
-rw-r--r--src/udp6.c15
3 files changed, 45 insertions, 0 deletions
diff --git a/src/ip_icmp.c b/src/ip_icmp.c
index 13a0e55..45694cd 100644
--- a/src/ip_icmp.c
+++ b/src/ip_icmp.c
@@ -176,6 +176,8 @@ void icmp_input(struct mbuf *m, int hlen)
} else {
struct socket *so;
struct sockaddr_storage addr;
+ int ttl;
+
so = socreate(slirp);
if (icmp_send(so, m, hlen) == 0) {
return;
@@ -207,6 +209,19 @@ void icmp_input(struct mbuf *m, int hlen)
return;
}
+ /*
+ * Check for TTL
+ */
+ ttl = ip->ip_ttl-1;
+ if (ttl <= 0) {
+ DEBUG_MISC("udp ttl exceeded");
+ icmp_send_error(m, ICMP_TIMXCEED, ICMP_TIMXCEED_INTRANS, 0,
+ NULL);
+ udp_detach(so);
+ break;
+ }
+ setsockopt(so->s, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl));
+
if (sendto(so->s, icmp_ping_msg, strlen(icmp_ping_msg), 0,
(struct sockaddr *)&addr, sockaddr_size(&addr)) == -1) {
DEBUG_MISC("icmp_input udp sendto tx errno = %d-%s", errno,
diff --git a/src/udp.c b/src/udp.c
index 0ad44d7..b5b4210 100644
--- a/src/udp.c
+++ b/src/udp.c
@@ -74,6 +74,7 @@ void udp_input(register struct mbuf *m, int iphlen)
struct socket *so;
struct sockaddr_storage lhost;
struct sockaddr_in *lhost4;
+ int ttl;
DEBUG_CALL("udp_input");
DEBUG_ARG("m = %p", m);
@@ -203,6 +204,20 @@ void udp_input(register struct mbuf *m, int iphlen)
m->m_data += iphlen;
/*
+ * Check for TTL
+ */
+ ttl = save_ip.ip_ttl-1;
+ if (ttl <= 0) {
+ m->m_len += iphlen;
+ m->m_data -= iphlen;
+ *ip = save_ip;
+ DEBUG_MISC("udp ttl exceeded");
+ icmp_send_error(m, ICMP_TIMXCEED, ICMP_TIMXCEED_INTRANS, 0, NULL);
+ goto bad;
+ }
+ setsockopt(so->s, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl));
+
+ /*
* Now we sendto() the packet.
*/
if (sosendto(so, m) == -1) {
diff --git a/src/udp6.c b/src/udp6.c
index 6f9486b..fdd8089 100644
--- a/src/udp6.c
+++ b/src/udp6.c
@@ -17,6 +17,7 @@ void udp6_input(struct mbuf *m)
int len;
struct socket *so;
struct sockaddr_in6 lhost;
+ int hop_limit;
DEBUG_CALL("udp6_input");
DEBUG_ARG("m = %p", m);
@@ -111,6 +112,20 @@ void udp6_input(struct mbuf *m)
m->m_data += iphlen;
/*
+ * Check for TTL
+ */
+ hop_limit = save_ip.ip_hl-1;
+ if (hop_limit <= 0) {
+ m->m_len += iphlen;
+ m->m_data -= iphlen;
+ *ip = save_ip;
+ DEBUG_MISC("udp ttl exceeded");
+ icmp6_send_error(m, ICMP6_TIMXCEED, ICMP6_TIMXCEED_INTRANS);
+ goto bad;
+ }
+ setsockopt(so->s, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &hop_limit, sizeof(hop_limit));
+
+ /*
* Now we sendto() the packet.
*/
if (sosendto(so, m) == -1) {