mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-05 00:33:55 -06:00
slirp: Adding ICMPv6 error sending
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>
This commit is contained in:
parent
de40abfecf
commit
fc6c9257c6
3 changed files with 84 additions and 3 deletions
|
@ -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
|
||||
*/
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue