Guillaume Subiron | 0d6ff71 | 2016-03-15 10:31:19 +0100 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2013 |
| 3 | * Guillaume Subiron, Yann Bordenave, Serigne Modou Wagne. |
| 4 | */ |
| 5 | |
| 6 | #include "qemu/osdep.h" |
| 7 | #include "slirp.h" |
| 8 | #include "ip6_icmp.h" |
| 9 | |
| 10 | /* |
| 11 | * IP initialization: fill in IP protocol switch table. |
| 12 | * All protocols not implemented in kernel go to raw IP protocol handler. |
| 13 | */ |
| 14 | void ip6_init(Slirp *slirp) |
| 15 | { |
| 16 | icmp6_init(slirp); |
| 17 | } |
| 18 | |
| 19 | void ip6_cleanup(Slirp *slirp) |
| 20 | { |
| 21 | icmp6_cleanup(slirp); |
| 22 | } |
| 23 | |
| 24 | void ip6_input(struct mbuf *m) |
| 25 | { |
| 26 | struct ip6 *ip6; |
Samuel Thibault | 0b11c03 | 2016-03-20 12:29:54 +0100 | [diff] [blame] | 27 | Slirp *slirp = m->slirp; |
| 28 | |
| 29 | if (!slirp->in6_enabled) { |
| 30 | goto bad; |
| 31 | } |
Guillaume Subiron | 0d6ff71 | 2016-03-15 10:31:19 +0100 | [diff] [blame] | 32 | |
| 33 | DEBUG_CALL("ip6_input"); |
| 34 | DEBUG_ARG("m = %lx", (long)m); |
| 35 | DEBUG_ARG("m_len = %d", m->m_len); |
| 36 | |
| 37 | if (m->m_len < sizeof(struct ip6)) { |
| 38 | goto bad; |
| 39 | } |
| 40 | |
| 41 | ip6 = mtod(m, struct ip6 *); |
| 42 | |
| 43 | if (ip6->ip_v != IP6VERSION) { |
| 44 | goto bad; |
| 45 | } |
| 46 | |
Yann Bordenave | fc6c925 | 2016-03-15 10:31:19 +0100 | [diff] [blame] | 47 | if (ntohs(ip6->ip_pl) > IF_MTU) { |
| 48 | icmp6_send_error(m, ICMP6_TOOBIG, 0); |
| 49 | goto bad; |
| 50 | } |
| 51 | |
Guillaume Subiron | 0d6ff71 | 2016-03-15 10:31:19 +0100 | [diff] [blame] | 52 | /* check ip_ttl for a correct ICMP reply */ |
| 53 | if (ip6->ip_hl == 0) { |
Yann Bordenave | fc6c925 | 2016-03-15 10:31:19 +0100 | [diff] [blame] | 54 | icmp6_send_error(m, ICMP6_TIMXCEED, ICMP6_TIMXCEED_INTRANS); |
Guillaume Subiron | 0d6ff71 | 2016-03-15 10:31:19 +0100 | [diff] [blame] | 55 | goto bad; |
| 56 | } |
| 57 | |
| 58 | /* |
| 59 | * Switch out to protocol's input routine. |
| 60 | */ |
| 61 | switch (ip6->ip_nh) { |
| 62 | case IPPROTO_TCP: |
Guillaume Subiron | 3feea44 | 2016-03-15 10:31:21 +0100 | [diff] [blame] | 63 | NTOHS(ip6->ip_pl); |
| 64 | tcp_input(m, sizeof(struct ip6), (struct socket *)NULL, AF_INET6); |
Guillaume Subiron | 0d6ff71 | 2016-03-15 10:31:19 +0100 | [diff] [blame] | 65 | break; |
| 66 | case IPPROTO_UDP: |
Guillaume Subiron | 15d62af | 2016-03-15 10:31:20 +0100 | [diff] [blame] | 67 | udp6_input(m); |
Guillaume Subiron | 0d6ff71 | 2016-03-15 10:31:19 +0100 | [diff] [blame] | 68 | break; |
| 69 | case IPPROTO_ICMPV6: |
| 70 | icmp6_input(m); |
| 71 | break; |
| 72 | default: |
| 73 | m_free(m); |
| 74 | } |
| 75 | return; |
| 76 | bad: |
| 77 | m_free(m); |
| 78 | } |