]> git.proxmox.com Git - mirror_qemu.git/blame - slirp/src/ip6.h
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
[mirror_qemu.git] / slirp / src / ip6.h
CommitLineData
0d6ff71a
GS
1/*
2 * Copyright (c) 2013
3 * Guillaume Subiron, Yann Bordenave, Serigne Modou Wagne.
4 */
5
2a6a4076
MA
6#ifndef SLIRP_IP6_H
7#define SLIRP_IP6_H
0d6ff71a 8
e429f296 9#include <glib.h>
a9d8b3ec 10#include <string.h>
0d6ff71a
GS
11
12#define ALLNODES_MULTICAST { .s6_addr = \
13 { 0xff, 0x02, 0x00, 0x00,\
14 0x00, 0x00, 0x00, 0x00,\
15 0x00, 0x00, 0x00, 0x00,\
16 0x00, 0x00, 0x00, 0x01 } }
17
18#define SOLICITED_NODE_PREFIX { .s6_addr = \
19 { 0xff, 0x02, 0x00, 0x00,\
20 0x00, 0x00, 0x00, 0x00,\
21 0x00, 0x00, 0x00, 0x01,\
22 0xff, 0x00, 0x00, 0x00 } }
23
24#define LINKLOCAL_ADDR { .s6_addr = \
25 { 0xfe, 0x80, 0x00, 0x00,\
26 0x00, 0x00, 0x00, 0x00,\
27 0x00, 0x00, 0x00, 0x00,\
28 0x00, 0x00, 0x00, 0x02 } }
29
1d17654e
ST
30#define ZERO_ADDR { .s6_addr = \
31 { 0x00, 0x00, 0x00, 0x00,\
32 0x00, 0x00, 0x00, 0x00,\
33 0x00, 0x00, 0x00, 0x00,\
34 0x00, 0x00, 0x00, 0x00 } }
35
0d6ff71a
GS
36static inline bool in6_equal(const struct in6_addr *a, const struct in6_addr *b)
37{
38 return memcmp(a, b, sizeof(*a)) == 0;
39}
40
41static inline bool in6_equal_net(const struct in6_addr *a,
42 const struct in6_addr *b,
43 int prefix_len)
44{
45 if (memcmp(a, b, prefix_len / 8) != 0) {
46 return 0;
47 }
48
49 if (prefix_len % 8 == 0) {
50 return 1;
51 }
52
53 return a->s6_addr[prefix_len / 8] >> (8 - (prefix_len % 8))
54 == b->s6_addr[prefix_len / 8] >> (8 - (prefix_len % 8));
55}
56
57static inline bool in6_equal_mach(const struct in6_addr *a,
58 const struct in6_addr *b,
59 int prefix_len)
60{
e88718fc
MAL
61 if (memcmp(&(a->s6_addr[DIV_ROUND_UP(prefix_len, 8)]),
62 &(b->s6_addr[DIV_ROUND_UP(prefix_len, 8)]),
63 16 - DIV_ROUND_UP(prefix_len, 8)) != 0) {
0d6ff71a
GS
64 return 0;
65 }
66
67 if (prefix_len % 8 == 0) {
68 return 1;
69 }
70
71 return (a->s6_addr[prefix_len / 8] & ((1U << (8 - (prefix_len % 8))) - 1))
72 == (b->s6_addr[prefix_len / 8] & ((1U << (8 - (prefix_len % 8))) - 1));
73}
74
75
76#define in6_equal_router(a)\
77 ((in6_equal_net(a, &slirp->vprefix_addr6, slirp->vprefix_len)\
78 && in6_equal_mach(a, &slirp->vhost_addr6, slirp->vprefix_len))\
79 || (in6_equal_net(a, &(struct in6_addr)LINKLOCAL_ADDR, 64)\
80 && in6_equal_mach(a, &slirp->vhost_addr6, 64)))
81
05061d85
GS
82#define in6_equal_dns(a)\
83 ((in6_equal_net(a, &slirp->vprefix_addr6, slirp->vprefix_len)\
84 && in6_equal_mach(a, &slirp->vnameserver_addr6, slirp->vprefix_len))\
85 || (in6_equal_net(a, &(struct in6_addr)LINKLOCAL_ADDR, 64)\
86 && in6_equal_mach(a, &slirp->vnameserver_addr6, 64)))
0d6ff71a
GS
87
88#define in6_equal_host(a)\
89 (in6_equal_router(a) || in6_equal_dns(a))
90
91#define in6_solicitednode_multicast(a)\
92 (in6_equal_net(a, &(struct in6_addr)SOLICITED_NODE_PREFIX, 104))
93
1d17654e
ST
94#define in6_zero(a)\
95 (in6_equal(a, &(struct in6_addr)ZERO_ADDR))
96
0d6ff71a
GS
97/* Compute emulated host MAC address from its ipv6 address */
98static inline void in6_compute_ethaddr(struct in6_addr ip,
99 uint8_t eth[ETH_ALEN])
100{
101 eth[0] = 0x52;
102 eth[1] = 0x56;
103 memcpy(&eth[2], &ip.s6_addr[16 - (ETH_ALEN - 2)], ETH_ALEN - 2);
104}
105
106/*
107 * Definitions for internet protocol version 6.
108 * Per RFC 2460, December 1998.
109 */
110#define IP6VERSION 6
111#define IP6_HOP_LIMIT 255
112
113/*
114 * Structure of an internet header, naked of options.
115 */
116struct ip6 {
e429f296 117#if G_BYTE_ORDER == G_BIG_ENDIAN
0d6ff71a
GS
118 uint32_t
119 ip_v:4, /* version */
120 ip_tc_hi:4, /* traffic class */
121 ip_tc_lo:4,
122 ip_fl_hi:4, /* flow label */
123 ip_fl_lo:16;
124#else
125 uint32_t
126 ip_tc_hi:4,
127 ip_v:4,
128 ip_fl_hi:4,
129 ip_tc_lo:4,
130 ip_fl_lo:16;
131#endif
132 uint16_t ip_pl; /* payload length */
133 uint8_t ip_nh; /* next header */
134 uint8_t ip_hl; /* hop limit */
135 struct in6_addr ip_src, ip_dst; /* source and dest address */
c74e3ae9 136};
0d6ff71a
GS
137
138/*
139 * IPv6 pseudo-header used by upper-layer protocols
140 */
141struct ip6_pseudohdr {
142 struct in6_addr ih_src; /* source internet address */
143 struct in6_addr ih_dst; /* destination internet address */
144 uint32_t ih_pl; /* upper-layer packet length */
145 uint16_t ih_zero_hi; /* zero */
146 uint8_t ih_zero_lo; /* zero */
147 uint8_t ih_nh; /* next header */
c74e3ae9 148};
0d6ff71a 149
c74e3ae9
PM
150/*
151 * We don't want to mark these ip6 structs as packed as they are naturally
152 * correctly aligned; instead assert that there is no stray padding.
153 * If we marked the struct as packed then we would be unable to take
154 * the address of any of the fields in it.
155 */
85a0e43c
ST
156G_STATIC_ASSERT(sizeof(struct ip6) == 40);
157G_STATIC_ASSERT(sizeof(struct ip6_pseudohdr) == 40);
0d6ff71a
GS
158
159#endif