All of lore.kernel.org
 help / color / mirror / Atom feed
From: Samuel Thibault <samuel.thibault@ens-lyon.org>
To: qemu-devel@nongnu.org
Cc: Thomas Huth <thuth@redhat.com>,
	zhanghailiang <zhang.zhanghailiang@huawei.com>,
	Li Zhijian <lizhijian@cn.fujitsu.com>,
	Stefan Hajnoczi <stefanha@gmail.com>,
	Jason Wang <jasowang@redhat.com>,
	Dave Gilbert <dgilbert@redhat.com>,
	Vasiliy Tolstov <v.tolstov@selfip.ru>,
	Huangpeng <peter.huangpeng@huawei.com>,
	Yann Bordenave <meow@meowstars.org>,
	Gonglei <arei.gonglei@huawei.com>,
	Jan Kiszka <jan.kiszka@siemens.com>,
	Samuel Thibault <samuel.thibault@ens-lyon.org>,
	Guillaume Subiron <maethor@subiron.org>
Subject: [Qemu-devel] [PATCHv10 03/11] slirp: Adding ICMPv6 error sending
Date: Tue,  8 Mar 2016 11:34:49 +0100	[thread overview]
Message-ID: <4b5bedfcd0bd3b16421ce17edadd91336aba23d3.1457433256.git.samuel.thibault@ens-lyon.org> (raw)
In-Reply-To: <cover.1457433256.git.samuel.thibault@ens-lyon.org>
In-Reply-To: <cover.1457433256.git.samuel.thibault@ens-lyon.org>

From: Yann Bordenave <meow@meowstars.org>

Adding icmp6_send_error to send ICMPv6 Error messages. This function is
simpler than the v4 version.
Adding some calls in various functions to send ICMP errors, when a
received packet is too big, or when its hop limit is 0.

Signed-off-by: Yann Bordenave <meow@meowstars.org>
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
Reviewed-by: Thomas Huth <thuth@redhat.com>
---
 slirp/ip6_icmp.c  | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 slirp/ip6_icmp.h  | 10 +++++++++
 slirp/ip6_input.c | 11 +++++++---
 3 files changed, 84 insertions(+), 3 deletions(-)

diff --git a/slirp/ip6_icmp.c b/slirp/ip6_icmp.c
index 9f3fd4a..9d61349 100644
--- a/slirp/ip6_icmp.c
+++ b/slirp/ip6_icmp.c
@@ -60,6 +60,72 @@ static void icmp6_send_echoreply(struct mbuf *m, Slirp *slirp, struct ip6 *ip,
     ip6_output(NULL, t, 0);
 }
 
+void icmp6_send_error(struct mbuf *m, uint8_t type, uint8_t code)
+{
+    Slirp *slirp = m->slirp;
+    struct mbuf *t;
+    struct ip6 *ip = mtod(m, struct ip6 *);
+
+    DEBUG_CALL("icmp6_send_error");
+    DEBUG_ARGS((dfd, " type = %d, code = %d\n", type, code));
+
+    if (IN6_IS_ADDR_MULTICAST(&ip->ip_src) ||
+            IN6_IS_ADDR_UNSPECIFIED(&ip->ip_src)) {
+        /* TODO icmp error? */
+        return;
+    }
+
+    t = m_get(slirp);
+
+    /* IPv6 packet */
+    struct ip6 *rip = mtod(t, struct ip6 *);
+    rip->ip_src = (struct in6_addr)LINKLOCAL_ADDR;
+    rip->ip_dst = ip->ip_src;
+#if !defined(_WIN32) || (_WIN32_WINNT >= 0x0600)
+    char addrstr[INET6_ADDRSTRLEN];
+    inet_ntop(AF_INET6, &rip->ip_dst, addrstr, INET6_ADDRSTRLEN);
+    DEBUG_ARG("target = %s", addrstr);
+#endif
+
+    rip->ip_nh = IPPROTO_ICMPV6;
+    const int error_data_len = min(m->m_len,
+            IF_MTU - (sizeof(struct ip6) + ICMP6_ERROR_MINLEN));
+    rip->ip_pl = htons(ICMP6_ERROR_MINLEN + error_data_len);
+    t->m_len = sizeof(struct ip6) + ntohs(rip->ip_pl);
+
+    /* ICMPv6 packet */
+    t->m_data += sizeof(struct ip6);
+    struct icmp6 *ricmp = mtod(t, struct icmp6 *);
+    ricmp->icmp6_type = type;
+    ricmp->icmp6_code = code;
+    ricmp->icmp6_cksum = 0;
+
+    switch (type) {
+    case ICMP6_UNREACH:
+    case ICMP6_TIMXCEED:
+        ricmp->icmp6_err.unused = 0;
+        break;
+    case ICMP6_TOOBIG:
+        ricmp->icmp6_err.mtu = htonl(IF_MTU);
+        break;
+    case ICMP6_PARAMPROB:
+        /* TODO: Handle this case */
+        break;
+    default:
+        g_assert_not_reached();
+        break;
+    }
+    t->m_data += ICMP6_ERROR_MINLEN;
+    memcpy(t->m_data, m->m_data, error_data_len);
+
+    /* Checksum */
+    t->m_data -= ICMP6_ERROR_MINLEN;
+    t->m_data -= sizeof(struct ip6);
+    ricmp->icmp6_cksum = ip6_cksum(t);
+
+    ip6_output(NULL, t, 0);
+}
+
 /*
  * Send NDP Router Advertisement
  */
diff --git a/slirp/ip6_icmp.h b/slirp/ip6_icmp.h
index b2c40d6..9460bf8 100644
--- a/slirp/ip6_icmp.h
+++ b/slirp/ip6_icmp.h
@@ -19,6 +19,12 @@ struct icmp6_echo { /* Echo Messages */
     uint16_t seq_num;
 };
 
+union icmp6_error_body {
+    uint32_t unused;
+    uint32_t pointer;
+    uint32_t mtu;
+};
+
 /*
  * NDP Messages
  */
@@ -82,6 +88,7 @@ struct icmp6 {
     uint8_t     icmp6_code;         /* type sub code */
     uint16_t    icmp6_cksum;        /* ones complement cksum of struct */
     union {
+        union icmp6_error_body error_body;
         struct icmp6_echo echo;
         struct ndp_rs ndp_rs;
         struct ndp_ra ndp_ra;
@@ -89,6 +96,7 @@ struct icmp6 {
         struct ndp_na ndp_na;
         struct ndp_redirect ndp_redirect;
     } icmp6_body;
+#define icmp6_err icmp6_body.error_body
 #define icmp6_echo icmp6_body.echo
 #define icmp6_nrs icmp6_body.ndp_rs
 #define icmp6_nra icmp6_body.ndp_ra
@@ -98,6 +106,7 @@ struct icmp6 {
 } QEMU_PACKED;
 
 #define ICMP6_MINLEN    4
+#define ICMP6_ERROR_MINLEN  8
 #define ICMP6_ECHO_MINLEN   8
 #define ICMP6_NDP_RS_MINLEN 8
 #define ICMP6_NDP_RA_MINLEN 16
@@ -197,6 +206,7 @@ struct ndpopt {
 void icmp6_init(Slirp *slirp);
 void icmp6_cleanup(Slirp *slirp);
 void icmp6_input(struct mbuf *);
+void icmp6_send_error(struct mbuf *m, uint8_t type, uint8_t code);
 void ndp_send_ra(Slirp *slirp);
 void ndp_send_ns(Slirp *slirp, struct in6_addr addr);
 
diff --git a/slirp/ip6_input.c b/slirp/ip6_input.c
index ca0007c..b6a438d 100644
--- a/slirp/ip6_input.c
+++ b/slirp/ip6_input.c
@@ -39,9 +39,14 @@ void ip6_input(struct mbuf *m)
         goto bad;
     }
 
+    if (ntohs(ip6->ip_pl) > IF_MTU) {
+        icmp6_send_error(m, ICMP6_TOOBIG, 0);
+        goto bad;
+    }
+
     /* check ip_ttl for a correct ICMP reply */
     if (ip6->ip_hl == 0) {
-        /*icmp_send_error(m, ICMP_TIMXCEED,ICMP_TIMXCEED_INTRANS, 0,"ttl");*/
+        icmp6_send_error(m, ICMP6_TIMXCEED, ICMP6_TIMXCEED_INTRANS);
         goto bad;
     }
 
@@ -50,10 +55,10 @@ void ip6_input(struct mbuf *m)
      */
     switch (ip6->ip_nh) {
     case IPPROTO_TCP:
-        /*tcp_input(m, hlen, (struct socket *)NULL);*/
+        icmp6_send_error(m, ICMP6_UNREACH, ICMP6_UNREACH_NO_ROUTE);
         break;
     case IPPROTO_UDP:
-        /*udp_input(m, hlen);*/
+        icmp6_send_error(m, ICMP6_UNREACH, ICMP6_UNREACH_NO_ROUTE);
         break;
     case IPPROTO_ICMPV6:
         icmp6_input(m);
-- 
2.7.0

  parent reply	other threads:[~2016-03-08 10:35 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-03-08 10:34 [Qemu-devel] [PATCHv10 0/11] slirp: Adding IPv6 support to Qemu -net user mode Samuel Thibault
2016-03-08 10:34 ` [Qemu-devel] [PATCHv10 01/11] slirp: Adding IPv6, ICMPv6 Echo and NDP autoconfiguration Samuel Thibault
2016-03-08 10:34 ` [Qemu-devel] [PATCHv10 02/11] slirp: Fix ICMP error sending Samuel Thibault
2016-03-08 10:34 ` Samuel Thibault [this message]
2016-03-08 10:34 ` [Qemu-devel] [PATCHv10 04/11] slirp: Adding IPv6 UDP support Samuel Thibault
2016-03-08 10:34 ` [Qemu-devel] [PATCHv10 05/11] slirp: Factorizing tcpiphdr structure with an union Samuel Thibault
2016-03-08 10:34 ` [Qemu-devel] [PATCHv10 06/11] slirp: Generalizing and neutralizing various TCP functions before adding IPv6 stuff Samuel Thibault
2016-03-08 10:34 ` [Qemu-devel] [PATCHv10 07/11] slirp: Reindent after refactoring Samuel Thibault
2016-03-08 10:34 ` [Qemu-devel] [PATCHv10 08/11] slirp: Handle IPv6 in TCP functions Samuel Thibault
2016-03-08 10:34 ` [Qemu-devel] [PATCHv10 09/11] slirp: Adding IPv6 address for DNS relay Samuel Thibault
2016-03-08 10:34 ` [Qemu-devel] [PATCHv10 10/11] qapi-schema, qemu-options & slirp: Adding Qemu options for IPv6 addresses Samuel Thibault
2016-03-10  8:52   ` Thomas Huth
2016-03-08 10:34 ` [Qemu-devel] [PATCHv10 11/11] slirp: Add IPv6 support to the TFTP code Samuel Thibault
2016-03-15  3:28 ` [Qemu-devel] [PATCHv10 0/11] slirp: Adding IPv6 support to Qemu -net user mode Jason Wang
2016-03-15  9:48   ` Samuel Thibault

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4b5bedfcd0bd3b16421ce17edadd91336aba23d3.1457433256.git.samuel.thibault@ens-lyon.org \
    --to=samuel.thibault@ens-lyon.org \
    --cc=arei.gonglei@huawei.com \
    --cc=dgilbert@redhat.com \
    --cc=jan.kiszka@siemens.com \
    --cc=jasowang@redhat.com \
    --cc=lizhijian@cn.fujitsu.com \
    --cc=maethor@subiron.org \
    --cc=meow@meowstars.org \
    --cc=peter.huangpeng@huawei.com \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanha@gmail.com \
    --cc=thuth@redhat.com \
    --cc=v.tolstov@selfip.ru \
    --cc=zhang.zhanghailiang@huawei.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.