slirp: Adding IPv6, ICMPv6 Echo and NDP autoconfiguration
[qemu/ar7.git] / slirp / ip6.h
blob731ee72d7748ecb6c460beea633753c38482135d
1 /*
2 * Copyright (c) 2013
3 * Guillaume Subiron, Yann Bordenave, Serigne Modou Wagne.
4 */
6 #ifndef SLIRP_IP6_H_
7 #define SLIRP_IP6_H_
9 #include "net/eth.h"
11 #define ALLNODES_MULTICAST { .s6_addr = \
12 { 0xff, 0x02, 0x00, 0x00,\
13 0x00, 0x00, 0x00, 0x00,\
14 0x00, 0x00, 0x00, 0x00,\
15 0x00, 0x00, 0x00, 0x01 } }
17 #define SOLICITED_NODE_PREFIX { .s6_addr = \
18 { 0xff, 0x02, 0x00, 0x00,\
19 0x00, 0x00, 0x00, 0x00,\
20 0x00, 0x00, 0x00, 0x01,\
21 0xff, 0x00, 0x00, 0x00 } }
23 #define LINKLOCAL_ADDR { .s6_addr = \
24 { 0xfe, 0x80, 0x00, 0x00,\
25 0x00, 0x00, 0x00, 0x00,\
26 0x00, 0x00, 0x00, 0x00,\
27 0x00, 0x00, 0x00, 0x02 } }
29 static inline bool in6_equal(const struct in6_addr *a, const struct in6_addr *b)
31 return memcmp(a, b, sizeof(*a)) == 0;
34 static inline bool in6_equal_net(const struct in6_addr *a,
35 const struct in6_addr *b,
36 int prefix_len)
38 if (memcmp(a, b, prefix_len / 8) != 0) {
39 return 0;
42 if (prefix_len % 8 == 0) {
43 return 1;
46 return a->s6_addr[prefix_len / 8] >> (8 - (prefix_len % 8))
47 == b->s6_addr[prefix_len / 8] >> (8 - (prefix_len % 8));
50 static inline bool in6_equal_mach(const struct in6_addr *a,
51 const struct in6_addr *b,
52 int prefix_len)
54 if (memcmp(&(a->s6_addr[(prefix_len + 7) / 8]),
55 &(b->s6_addr[(prefix_len + 7) / 8]),
56 16 - (prefix_len + 7) / 8) != 0) {
57 return 0;
60 if (prefix_len % 8 == 0) {
61 return 1;
64 return (a->s6_addr[prefix_len / 8] & ((1U << (8 - (prefix_len % 8))) - 1))
65 == (b->s6_addr[prefix_len / 8] & ((1U << (8 - (prefix_len % 8))) - 1));
69 #define in6_equal_router(a)\
70 ((in6_equal_net(a, &slirp->vprefix_addr6, slirp->vprefix_len)\
71 && in6_equal_mach(a, &slirp->vhost_addr6, slirp->vprefix_len))\
72 || (in6_equal_net(a, &(struct in6_addr)LINKLOCAL_ADDR, 64)\
73 && in6_equal_mach(a, &slirp->vhost_addr6, 64)))
75 #define in6_equal_dns(a) 0
77 #define in6_equal_host(a)\
78 (in6_equal_router(a) || in6_equal_dns(a))
80 #define in6_solicitednode_multicast(a)\
81 (in6_equal_net(a, &(struct in6_addr)SOLICITED_NODE_PREFIX, 104))
83 /* Compute emulated host MAC address from its ipv6 address */
84 static inline void in6_compute_ethaddr(struct in6_addr ip,
85 uint8_t eth[ETH_ALEN])
87 eth[0] = 0x52;
88 eth[1] = 0x56;
89 memcpy(&eth[2], &ip.s6_addr[16 - (ETH_ALEN - 2)], ETH_ALEN - 2);
93 * Definitions for internet protocol version 6.
94 * Per RFC 2460, December 1998.
96 #define IP6VERSION 6
97 #define IP6_HOP_LIMIT 255
100 * Structure of an internet header, naked of options.
102 struct ip6 {
103 #ifdef HOST_WORDS_BIGENDIAN
104 uint32_t
105 ip_v:4, /* version */
106 ip_tc_hi:4, /* traffic class */
107 ip_tc_lo:4,
108 ip_fl_hi:4, /* flow label */
109 ip_fl_lo:16;
110 #else
111 uint32_t
112 ip_tc_hi:4,
113 ip_v:4,
114 ip_fl_hi:4,
115 ip_tc_lo:4,
116 ip_fl_lo:16;
117 #endif
118 uint16_t ip_pl; /* payload length */
119 uint8_t ip_nh; /* next header */
120 uint8_t ip_hl; /* hop limit */
121 struct in6_addr ip_src, ip_dst; /* source and dest address */
122 } QEMU_PACKED;
125 * IPv6 pseudo-header used by upper-layer protocols
127 struct ip6_pseudohdr {
128 struct in6_addr ih_src; /* source internet address */
129 struct in6_addr ih_dst; /* destination internet address */
130 uint32_t ih_pl; /* upper-layer packet length */
131 uint16_t ih_zero_hi; /* zero */
132 uint8_t ih_zero_lo; /* zero */
133 uint8_t ih_nh; /* next header */
134 } QEMU_PACKED;
137 #endif