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 | |
Markus Armbruster | 121d071 | 2016-06-29 10:12:57 +0200 | [diff] [blame] | 6 | #ifndef SLIRP_IP6_ICMP_H |
| 7 | #define SLIRP_IP6_ICMP_H |
Guillaume Subiron | 0d6ff71 | 2016-03-15 10:31:19 +0100 | [diff] [blame] | 8 | |
| 9 | /* |
| 10 | * Interface Control Message Protocol version 6 Definitions. |
| 11 | * Per RFC 4443, March 2006. |
| 12 | * |
| 13 | * Network Discover Protocol Definitions. |
| 14 | * Per RFC 4861, September 2007. |
| 15 | */ |
| 16 | |
| 17 | struct icmp6_echo { /* Echo Messages */ |
| 18 | uint16_t id; |
| 19 | uint16_t seq_num; |
| 20 | }; |
| 21 | |
Yann Bordenave | fc6c925 | 2016-03-15 10:31:19 +0100 | [diff] [blame] | 22 | union icmp6_error_body { |
| 23 | uint32_t unused; |
| 24 | uint32_t pointer; |
| 25 | uint32_t mtu; |
| 26 | }; |
| 27 | |
Guillaume Subiron | 0d6ff71 | 2016-03-15 10:31:19 +0100 | [diff] [blame] | 28 | /* |
| 29 | * NDP Messages |
| 30 | */ |
| 31 | struct ndp_rs { /* Router Solicitation Message */ |
| 32 | uint32_t reserved; |
| 33 | }; |
| 34 | |
| 35 | struct ndp_ra { /* Router Advertisement Message */ |
| 36 | uint8_t chl; /* Cur Hop Limit */ |
| 37 | #ifdef HOST_WORDS_BIGENDIAN |
| 38 | uint8_t |
| 39 | M:1, |
| 40 | O:1, |
| 41 | reserved:6; |
| 42 | #else |
| 43 | uint8_t |
| 44 | reserved:6, |
| 45 | O:1, |
| 46 | M:1; |
| 47 | #endif |
| 48 | uint16_t lifetime; /* Router Lifetime */ |
| 49 | uint32_t reach_time; /* Reachable Time */ |
| 50 | uint32_t retrans_time; /* Retrans Timer */ |
| 51 | } QEMU_PACKED; |
| 52 | |
| 53 | struct ndp_ns { /* Neighbor Solicitation Message */ |
| 54 | uint32_t reserved; |
| 55 | struct in6_addr target; /* Target Address */ |
| 56 | } QEMU_PACKED; |
| 57 | |
| 58 | struct ndp_na { /* Neighbor Advertisement Message */ |
| 59 | #ifdef HOST_WORDS_BIGENDIAN |
| 60 | uint32_t |
| 61 | R:1, /* Router Flag */ |
| 62 | S:1, /* Solicited Flag */ |
| 63 | O:1, /* Override Flag */ |
| 64 | reserved_hi:5, |
| 65 | reserved_lo:24; |
| 66 | #else |
| 67 | uint32_t |
| 68 | reserved_hi:5, |
| 69 | O:1, |
| 70 | S:1, |
| 71 | R:1, |
| 72 | reserved_lo:24; |
| 73 | #endif |
| 74 | struct in6_addr target; /* Target Address */ |
| 75 | } QEMU_PACKED; |
| 76 | |
| 77 | struct ndp_redirect { |
| 78 | uint32_t reserved; |
| 79 | struct in6_addr target; /* Target Address */ |
| 80 | struct in6_addr dest; /* Destination Address */ |
| 81 | } QEMU_PACKED; |
| 82 | |
| 83 | /* |
| 84 | * Structure of an icmpv6 header. |
| 85 | */ |
| 86 | struct icmp6 { |
| 87 | uint8_t icmp6_type; /* type of message, see below */ |
| 88 | uint8_t icmp6_code; /* type sub code */ |
| 89 | uint16_t icmp6_cksum; /* ones complement cksum of struct */ |
| 90 | union { |
Yann Bordenave | fc6c925 | 2016-03-15 10:31:19 +0100 | [diff] [blame] | 91 | union icmp6_error_body error_body; |
Guillaume Subiron | 0d6ff71 | 2016-03-15 10:31:19 +0100 | [diff] [blame] | 92 | struct icmp6_echo echo; |
| 93 | struct ndp_rs ndp_rs; |
| 94 | struct ndp_ra ndp_ra; |
| 95 | struct ndp_ns ndp_ns; |
| 96 | struct ndp_na ndp_na; |
| 97 | struct ndp_redirect ndp_redirect; |
| 98 | } icmp6_body; |
Yann Bordenave | fc6c925 | 2016-03-15 10:31:19 +0100 | [diff] [blame] | 99 | #define icmp6_err icmp6_body.error_body |
Guillaume Subiron | 0d6ff71 | 2016-03-15 10:31:19 +0100 | [diff] [blame] | 100 | #define icmp6_echo icmp6_body.echo |
| 101 | #define icmp6_nrs icmp6_body.ndp_rs |
| 102 | #define icmp6_nra icmp6_body.ndp_ra |
| 103 | #define icmp6_nns icmp6_body.ndp_ns |
| 104 | #define icmp6_nna icmp6_body.ndp_na |
| 105 | #define icmp6_redirect icmp6_body.ndp_redirect |
| 106 | } QEMU_PACKED; |
| 107 | |
| 108 | #define ICMP6_MINLEN 4 |
Yann Bordenave | fc6c925 | 2016-03-15 10:31:19 +0100 | [diff] [blame] | 109 | #define ICMP6_ERROR_MINLEN 8 |
Guillaume Subiron | 0d6ff71 | 2016-03-15 10:31:19 +0100 | [diff] [blame] | 110 | #define ICMP6_ECHO_MINLEN 8 |
| 111 | #define ICMP6_NDP_RS_MINLEN 8 |
| 112 | #define ICMP6_NDP_RA_MINLEN 16 |
| 113 | #define ICMP6_NDP_NS_MINLEN 24 |
| 114 | #define ICMP6_NDP_NA_MINLEN 24 |
| 115 | #define ICMP6_NDP_REDIRECT_MINLEN 40 |
| 116 | |
| 117 | /* |
| 118 | * NDP Options |
| 119 | */ |
| 120 | struct ndpopt { |
| 121 | uint8_t ndpopt_type; /* Option type */ |
| 122 | uint8_t ndpopt_len; /* /!\ In units of 8 octets */ |
| 123 | union { |
| 124 | unsigned char linklayer_addr[6]; /* Source/Target Link-layer */ |
Samuel Thibault | f7725df | 2016-03-20 16:02:52 +0100 | [diff] [blame] | 125 | #define ndpopt_linklayer ndpopt_body.linklayer_addr |
Guillaume Subiron | 0d6ff71 | 2016-03-15 10:31:19 +0100 | [diff] [blame] | 126 | struct prefixinfo { /* Prefix Information */ |
| 127 | uint8_t prefix_length; |
| 128 | #ifdef HOST_WORDS_BIGENDIAN |
| 129 | uint8_t L:1, A:1, reserved1:6; |
| 130 | #else |
| 131 | uint8_t reserved1:6, A:1, L:1; |
| 132 | #endif |
| 133 | uint32_t valid_lt; /* Valid Lifetime */ |
| 134 | uint32_t pref_lt; /* Preferred Lifetime */ |
| 135 | uint32_t reserved2; |
| 136 | struct in6_addr prefix; |
| 137 | } QEMU_PACKED prefixinfo; |
Guillaume Subiron | 0d6ff71 | 2016-03-15 10:31:19 +0100 | [diff] [blame] | 138 | #define ndpopt_prefixinfo ndpopt_body.prefixinfo |
Samuel Thibault | f7725df | 2016-03-20 16:02:52 +0100 | [diff] [blame] | 139 | struct rdnss { |
| 140 | uint16_t reserved; |
| 141 | uint32_t lifetime; |
| 142 | struct in6_addr addr; |
| 143 | } QEMU_PACKED rdnss; |
| 144 | #define ndpopt_rdnss ndpopt_body.rdnss |
| 145 | } ndpopt_body; |
Guillaume Subiron | 0d6ff71 | 2016-03-15 10:31:19 +0100 | [diff] [blame] | 146 | } QEMU_PACKED; |
| 147 | |
| 148 | /* NDP options type */ |
| 149 | #define NDPOPT_LINKLAYER_SOURCE 1 /* Source Link-Layer Address */ |
| 150 | #define NDPOPT_LINKLAYER_TARGET 2 /* Target Link-Layer Address */ |
| 151 | #define NDPOPT_PREFIX_INFO 3 /* Prefix Information */ |
Samuel Thibault | f7725df | 2016-03-20 16:02:52 +0100 | [diff] [blame] | 152 | #define NDPOPT_RDNSS 25 /* Recursive DNS Server Address */ |
Guillaume Subiron | 0d6ff71 | 2016-03-15 10:31:19 +0100 | [diff] [blame] | 153 | |
| 154 | /* NDP options size, in octets. */ |
| 155 | #define NDPOPT_LINKLAYER_LEN 8 |
| 156 | #define NDPOPT_PREFIXINFO_LEN 32 |
Samuel Thibault | f7725df | 2016-03-20 16:02:52 +0100 | [diff] [blame] | 157 | #define NDPOPT_RDNSS_LEN 24 |
Guillaume Subiron | 0d6ff71 | 2016-03-15 10:31:19 +0100 | [diff] [blame] | 158 | |
| 159 | /* |
| 160 | * Definition of type and code field values. |
| 161 | * Per https://www.iana.org/assignments/icmpv6-parameters/icmpv6-parameters.xml |
| 162 | * Last Updated 2012-11-12 |
| 163 | */ |
| 164 | |
| 165 | /* Errors */ |
| 166 | #define ICMP6_UNREACH 1 /* Destination Unreachable */ |
| 167 | #define ICMP6_UNREACH_NO_ROUTE 0 /* no route to dest */ |
| 168 | #define ICMP6_UNREACH_DEST_PROHIB 1 /* com with dest prohibited */ |
| 169 | #define ICMP6_UNREACH_SCOPE 2 /* beyond scope of src addr */ |
| 170 | #define ICMP6_UNREACH_ADDRESS 3 /* address unreachable */ |
| 171 | #define ICMP6_UNREACH_PORT 4 /* port unreachable */ |
| 172 | #define ICMP6_UNREACH_SRC_FAIL 5 /* src addr failed */ |
| 173 | #define ICMP6_UNREACH_REJECT_ROUTE 6 /* reject route to dest */ |
| 174 | #define ICMP6_UNREACH_SRC_HDR_ERROR 7 /* error in src routing header */ |
| 175 | #define ICMP6_TOOBIG 2 /* Packet Too Big */ |
| 176 | #define ICMP6_TIMXCEED 3 /* Time Exceeded */ |
| 177 | #define ICMP6_TIMXCEED_INTRANS 0 /* hop limit exceeded in transit */ |
| 178 | #define ICMP6_TIMXCEED_REASS 1 /* ttl=0 in reass */ |
| 179 | #define ICMP6_PARAMPROB 4 /* Parameter Problem */ |
| 180 | #define ICMP6_PARAMPROB_HDR_FIELD 0 /* err header field */ |
| 181 | #define ICMP6_PARAMPROB_NXTHDR_TYPE 1 /* unrecognized Next Header type */ |
| 182 | #define ICMP6_PARAMPROB_IPV6_OPT 2 /* unrecognized IPv6 option */ |
| 183 | |
| 184 | /* Informational Messages */ |
| 185 | #define ICMP6_ECHO_REQUEST 128 /* Echo Request */ |
| 186 | #define ICMP6_ECHO_REPLY 129 /* Echo Reply */ |
| 187 | #define ICMP6_NDP_RS 133 /* Router Solicitation (NDP) */ |
| 188 | #define ICMP6_NDP_RA 134 /* Router Advertisement (NDP) */ |
| 189 | #define ICMP6_NDP_NS 135 /* Neighbor Solicitation (NDP) */ |
| 190 | #define ICMP6_NDP_NA 136 /* Neighbor Advertisement (NDP) */ |
| 191 | #define ICMP6_NDP_REDIRECT 137 /* Redirect Message (NDP) */ |
| 192 | |
| 193 | /* |
| 194 | * Router Configuration Variables (rfc4861#section-6) |
| 195 | */ |
| 196 | #define NDP_IsRouter 1 |
| 197 | #define NDP_AdvSendAdvertisements 1 |
| 198 | #define NDP_MaxRtrAdvInterval 600000 |
| 199 | #define NDP_MinRtrAdvInterval ((NDP_MaxRtrAdvInterval >= 9) ? \ |
| 200 | NDP_MaxRtrAdvInterval / 3 : \ |
| 201 | NDP_MaxRtrAdvInterval) |
| 202 | #define NDP_AdvManagedFlag 0 |
| 203 | #define NDP_AdvOtherConfigFlag 0 |
| 204 | #define NDP_AdvLinkMTU 0 |
| 205 | #define NDP_AdvReachableTime 0 |
| 206 | #define NDP_AdvRetransTime 0 |
| 207 | #define NDP_AdvCurHopLimit 64 |
| 208 | #define NDP_AdvDefaultLifetime ((3 * NDP_MaxRtrAdvInterval) / 1000) |
| 209 | #define NDP_AdvValidLifetime 86400 |
| 210 | #define NDP_AdvOnLinkFlag 1 |
| 211 | #define NDP_AdvPrefLifetime 14400 |
| 212 | #define NDP_AdvAutonomousFlag 1 |
| 213 | |
| 214 | void icmp6_init(Slirp *slirp); |
| 215 | void icmp6_cleanup(Slirp *slirp); |
| 216 | void icmp6_input(struct mbuf *); |
Yann Bordenave | fc6c925 | 2016-03-15 10:31:19 +0100 | [diff] [blame] | 217 | void icmp6_send_error(struct mbuf *m, uint8_t type, uint8_t code); |
Guillaume Subiron | 0d6ff71 | 2016-03-15 10:31:19 +0100 | [diff] [blame] | 218 | void ndp_send_ra(Slirp *slirp); |
| 219 | void ndp_send_ns(Slirp *slirp, struct in6_addr addr); |
| 220 | |
| 221 | #endif |